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 #ifndef LASS_GUARDIAN_OF_INCLUSION_PRIM_SIMPLE_TRIANGLE_MESH_3D_INL
00046 #define LASS_GUARDIAN_OF_INCLUSION_PRIM_SIMPLE_TRIANGLE_MESH_3D_INL
00047
00048 #include "prim_common.h"
00049 #include "triangle_mesh_3d.h"
00050 #include "../stde/range_algorithm.h"
00051 #include "../stde/extended_iterator.h"
00052 #include "point_3dh.h"
00053 #include "point_2dh.h"
00054 #include <algorithm>
00055
00056 namespace lass
00057 {
00058 namespace prim
00059 {
00060
00061
00062
00063 template <typename T, template <typename, typename, typename> class BHV, typename SH>
00064 TriangleMesh3D<T, BHV, SH>::TriangleMesh3D()
00065 {
00066 }
00067
00068
00069
00070 template <typename T, template <typename, typename, typename> class BHV, typename SH>
00071 template
00072 <
00073 typename VertexInputRange, typename IndexTriangleInputRange
00074 >
00075 TriangleMesh3D<T, BHV, SH>::TriangleMesh3D(
00076 const VertexInputRange& vertices, const IndexTriangleInputRange& triangles):
00077 vertices_(vertices.begin(), vertices.end()),
00078 normals_(),
00079 uvs_()
00080 {
00081 buildMesh(triangles);
00082 }
00083
00084
00085
00086 template <typename T, template <typename, typename, typename> class BHV, typename SH>
00087 template
00088 <
00089 typename VertexInputRange, typename NormalInputRange,
00090 typename UvInputRange, typename IndexTriangleInputRange
00091 >
00092 TriangleMesh3D<T, BHV, SH>::TriangleMesh3D(
00093 const VertexInputRange& vertices, const NormalInputRange& normals,
00094 const UvInputRange& uvs, const IndexTriangleInputRange& triangles):
00095 vertices_(vertices.begin(), vertices.end()),
00096 normals_(normals.begin(), normals.end()),
00097 uvs_(uvs.begin(), uvs.end())
00098 {
00099 buildMesh(triangles);
00100 }
00101
00102
00103
00104 template <typename T, template <typename, typename, typename> class BHV, typename SH>
00105 const typename TriangleMesh3D<T, BHV, SH>::TTriangles&
00106 TriangleMesh3D<T, BHV, SH>::triangles() const
00107 {
00108 return triangles_;
00109 }
00110
00111
00112
00113 template <typename T, template <typename, typename, typename> class BHV, typename SH>
00114 const typename TriangleMesh3D<T, BHV, SH>::TVertices&
00115 TriangleMesh3D<T, BHV, SH>::vertices() const
00116 {
00117 return vertices_;
00118 }
00119
00120
00121
00122 template <typename T, template <typename, typename, typename> class BHV, typename SH>
00123 const typename TriangleMesh3D<T, BHV, SH>::TNormals&
00124 TriangleMesh3D<T, BHV, SH>::normals() const
00125 {
00126 return normals_;
00127 }
00128
00129
00130
00131 template <typename T, template <typename, typename, typename> class BHV, typename SH>
00132 const typename TriangleMesh3D<T, BHV, SH>::TUvs&
00133 TriangleMesh3D<T, BHV, SH>::uvs() const
00134 {
00135 return uvs_;
00136 }
00137
00138
00139
00140 template <typename T, template <typename, typename, typename> class BHV, typename SH>
00141 template <typename OutputIterator>
00142 OutputIterator TriangleMesh3D<T, BHV, SH>::indexTriangles(OutputIterator triangles) const
00143 {
00144 typename TTriangles::const_iterator triangle;
00145 for (triangle = triangles_.begin(); triangle != triangles_.end(); ++triangle)
00146 {
00147 TIndexTriangle indexTriangle;
00148 for (std::size_t k = 0; k < 3; ++k)
00149 {
00150 LASS_ASSERT(triangle->vertices[k]);
00151 indexTriangle.vertices[k] = triangle->vertices[k] - &vertices_.front();
00152 indexTriangle.normals[k] = triangle->normals[k] ?
00153 triangle->normals[k] - &normals_.front() : IndexTriangle::null();
00154 indexTriangle.uvs[k] = triangle->uvs[k] ?
00155 triangle->uvs[k] - &uvs_.front() : IndexTriangle::null();
00156 }
00157 *triangles++ = indexTriangle;
00158 }
00159 return triangles;
00160 }
00161
00162
00163
00164 template <typename T, template <typename, typename, typename> class BHV, typename SH>
00165 const typename TriangleMesh3D<T, BHV, SH>::TAabb
00166 TriangleMesh3D<T, BHV, SH>::aabb() const
00167 {
00168 LASS_ASSERT(tree_.isEmpty() == triangles_.empty());
00169 return tree_.aabb();
00170 }
00171
00172
00173
00174 template <typename T, template <typename, typename, typename> class BHV, typename SH>
00175 const typename TriangleMesh3D<T, BHV, SH>::TValue
00176 TriangleMesh3D<T, BHV, SH>::area() const
00177 {
00178 TValue result = 0;
00179
00180 typename TTriangles::const_iterator triangle;
00181 for (triangle = triangles_.begin(); triangle != triangles_.end(); ++triangle)
00182 {
00183 const TVector a = *triangle->vertices[1] - *triangle->vertices[0];
00184 const TVector b = *triangle->vertices[2] - *triangle->vertices[0];
00185 const TVector n = cross(a, b);
00186 result += n.norm() / 2;
00187 }
00188
00189 return result;
00190 }
00191
00192
00193
00194 template <typename T, template <typename, typename, typename> class BHV, typename SH>
00195 void TriangleMesh3D<T, BHV, SH>::smoothNormals(TParam maxAngleInRadians)
00196 {
00197 const std::size_t numTriangles = triangles_.size();
00198 const std::size_t numVertices = vertices_.size();
00199 const TValue minDot = num::cos(maxAngleInRadians);
00200
00201
00202
00203 TNormals faceNormals(numTriangles);
00204 TNormals vertexNormals(numVertices);
00205 for (std::size_t i = 0; i < numTriangles; ++i)
00206 {
00207 const Triangle& triangle = triangles_[i];
00208
00209 bool isDegenerated = false;
00210 for (std::size_t prevK = 2, k = 0; k < 3; prevK = k++)
00211 {
00212 isDegenerated |= (*triangle.vertices[k] == *triangle.vertices[prevK]);
00213 }
00214 if (isDegenerated)
00215 {
00216 faceNormals[i] = TVector();
00217 continue;
00218 }
00219
00220 const TVector edges[3] =
00221 {
00222 (*triangle.vertices[1] - *triangle.vertices[0]).normal(),
00223 (*triangle.vertices[2] - *triangle.vertices[1]).normal(),
00224 (*triangle.vertices[0] - *triangle.vertices[2]).normal()
00225 };
00226
00227 const TVector n = cross(edges[0], edges[1]).normal();
00228 faceNormals[i] = n;
00229
00230 if (!n.isZero() && !n.isNaN())
00231 {
00232 for (std::size_t prevK = 2, k = 0; k < 3; prevK = k++)
00233 {
00234 const std::size_t j = triangle.vertices[k] - &vertices_.front();
00235 vertexNormals[j] += n * num::acos(-dot(edges[prevK], edges[k]));
00236 }
00237 }
00238 }
00239 stde::for_each_r(vertexNormals, std::mem_fun_ref(&TVector::normalize));
00240
00241
00242
00243 std::vector<std::size_t> usedVertexNormals(vertices_.size(), IndexTriangle::null());
00244 std::vector<std::size_t> usedFaceNormals(triangles_.size(), IndexTriangle::null());
00245 std::size_t normalCount = 0;
00246 for (std::size_t i = 0; i < numTriangles; ++i)
00247 {
00248 const Triangle& triangle = triangles_[i];
00249 for (std::size_t k = 0; k < 3; ++k)
00250 {
00251 const std::size_t j = triangle.vertices[k] - &vertices_.front();
00252 if (dot(faceNormals[i], vertexNormals[j]) >= minDot)
00253 {
00254 if (usedVertexNormals[j] == IndexTriangle::null())
00255 {
00256 usedVertexNormals[j] = normalCount++;
00257 }
00258 }
00259 else
00260 {
00261 if (usedFaceNormals[i] == IndexTriangle::null())
00262 {
00263 usedFaceNormals[i] = normalCount++;
00264 }
00265 }
00266 }
00267 }
00268
00269
00270 normals_.resize(normalCount);
00271 for (std::size_t i = 0; i < numTriangles; ++i)
00272 {
00273 if (usedFaceNormals[i] != IndexTriangle::null())
00274 {
00275 normals_[usedFaceNormals[i]] = faceNormals[i];
00276 }
00277 }
00278 for (std::size_t i = 0; i < numVertices; ++i)
00279 {
00280 if (usedVertexNormals[i] != IndexTriangle::null())
00281 {
00282 normals_[usedVertexNormals[i]] = vertexNormals[i];
00283 }
00284 }
00285
00286
00287
00288 for (std::size_t i = 0; i < numTriangles; ++i)
00289 {
00290 Triangle& triangle = triangles_[i];
00291 for (std::size_t k = 0; k < 3; ++k)
00292 {
00293 const std::size_t j = triangle.vertices[k] - &vertices_.front();
00294 if (dot(faceNormals[i], vertexNormals[j]) >= minDot)
00295 {
00296 LASS_ASSERT(usedVertexNormals[j] != IndexTriangle::null());
00297 triangle.normals[k] = &normals_[usedVertexNormals[j]];
00298 }
00299 else
00300 {
00301 LASS_ASSERT(usedFaceNormals[i] != IndexTriangle::null());
00302 triangle.normals[k] = &normals_[usedFaceNormals[i]];
00303 }
00304 }
00305 }
00306 }
00307
00308
00309
00310
00311
00312 template <typename T, template <typename, typename, typename> class BHV, typename SH>
00313 void TriangleMesh3D<T, BHV, SH>::flatFaces()
00314 {
00315 normals_.clear();
00316 for (typename TTriangles::iterator triangle = triangles_.begin();
00317 triangle != triangles_.end(); ++triangle)
00318 {
00319 std::fill(triangle->normals, triangle->normals + 3, static_cast<TVector*>(0));
00320 }
00321 }
00322
00323
00324 template <typename T, template <typename, typename, typename> class BHV, typename SH>
00325 void TriangleMesh3D<T, BHV, SH>::loopSubdivision(unsigned level)
00326 {
00327 #pragma LASS_TODO("refactor this function [Bramz]")
00328 if (triangles_.empty())
00329 {
00330 return;
00331 }
00332
00333 while (level-- > 0)
00334 {
00335
00336
00337 subdivide();
00338
00339
00340 TVertices newVertices = vertices_;
00341 TNormals newNormals = normals_;
00342 TUvs newUvs = uvs_;
00343 const TPoint* const firstVertex = &vertices_[0];
00344 const TVector* const firstNormal = &normals_[0];
00345 const TUv* const firstUv = &uvs_[0];
00346
00347
00348
00349
00350 TVertexTriangles vertexTriangles;
00351 findVertexTriangles(vertexTriangles);
00352 TVertexRing ring;
00353 TVertexRing creases;
00354 TNormalRing normalRing;
00355 TUvRing uvRing;
00356 const size_t numVertices = vertices_.size();
00357 for (size_t i = 0; i < numVertices; ++i)
00358 {
00359 if (const Triangle* const vertexTriangle = vertexTriangles[i])
00360 {
00361 const TPoint& vertex = vertices_[i];
00362 findVertexRing(vertex, vertexTriangle, ring, creases, normalRing, uvRing);
00363 const size_t nRing = ring.size();
00364 const size_t nCreases = creases.size();
00365 LASS_ASSERT(nRing >= 2);
00366 if (nCreases == 2)
00367 {
00368
00369 newVertices[i] = TPoint(.75f * vertex.position() + .125f * (creases[0].position() + creases[1].position()));
00370 }
00371 else if (nRing > 2 && nCreases == 0)
00372 {
00373
00374 const TValue beta = nRing == 6 ?
00375 .125f : 2 * (.625f - num::sqr(.375f + .25f * num::cos(2 * TNumTraits::pi / nRing))) / nRing;
00376 TVector newVertex = (1 - nRing * beta) * vertex.position();
00377 for (size_t j = 0; j < nRing; ++j)
00378 {
00379 newVertex += beta * ring[j].position();
00380 }
00381 newVertices[i] = TPoint(newVertex);
00382 if (!uvRing.empty())
00383 {
00384 LASS_ASSERT(uvRing.size() == nRing);
00385 const size_t k = vertexTriangle->side(&vertex);
00386 LASS_ASSERT(k < 3 && vertexTriangle->uvs[k]);
00387 const TUv& uv = *vertexTriangle->uvs[k];
00388 typename TUv::TVector newUv = (1 - nRing * beta) * uv.position();
00389 for (size_t j = 0; j < nRing; ++j)
00390 {
00391 newUv += beta * uvRing[j].position();
00392 }
00393 newUvs[&uv - firstUv] = TUv(newUv);
00394 }
00395 }
00396 }
00397 }
00398
00399
00400
00401
00402 for (typename TTriangles::iterator triangle = triangles_.begin();
00403 triangle != triangles_.end(); ++triangle)
00404 {
00405 for (size_t k = 0; k < 3; ++k)
00406 {
00407 triangle->vertices[k] = &newVertices[triangle->vertices[k] - firstVertex];
00408 triangle->normals[k] = triangle->normals[k] ? &newNormals[triangle->normals[k] - firstNormal] : 0;
00409 triangle->uvs[k] = triangle->uvs[k] ? &newUvs[triangle->uvs[k] - firstUv] : 0;
00410 triangle->creaseLevel[k] = triangle->creaseLevel[k] > 0 ? triangle->creaseLevel[k] - 1 : 0;
00411 }
00412 }
00413 vertices_.swap(newVertices);
00414 normals_.swap(newNormals);
00415 uvs_.swap(newUvs);
00416 }
00417 tree_.reset(triangles_.begin(), triangles_.end());
00418 }
00419
00420
00421
00422
00423
00424 template <typename T, template <typename, typename, typename> class BHV, typename SH>
00425 void TriangleMesh3D<T, BHV, SH>::autoSew()
00426 {
00427 typedef std::vector<PositionalEdge> TEdges;
00428
00429
00430
00431 const size_t numTriangles = triangles_.size();
00432 TEdges edges;
00433 edges.reserve(numBoundaryEdges_);
00434 for (size_t i = 0; i < numTriangles; ++i)
00435 {
00436 Triangle& triangle = triangles_[i];
00437 for (size_t k1 = 2, k2 = 0; k2 < 3; k1 = k2++)
00438 {
00439 if (triangle.others[k1] == 0)
00440 {
00441 edges.push_back(PositionalEdge(&triangle, k1, k2));
00442 }
00443 }
00444 }
00445 LASS_ASSERT(edges.size() == numBoundaryEdges_);
00446 std::sort(edges.begin(), edges.end());
00447
00448
00449
00450 for (size_t i = 0; i < numTriangles; ++i)
00451 {
00452 Triangle& triangle = triangles_[i];
00453 for (size_t k1 = 2, k2 = 0; k2 < 3; k1 = k2++)
00454 {
00455 if (triangle.others[k1] == 0)
00456 {
00457 const PositionalEdge bait(&triangle, k2, k1);
00458 const typename TEdges::const_iterator haul =
00459 std::lower_bound(edges.begin(), edges.end(), bait);
00460 if (haul != edges.end() && !(bait < *haul) &&
00461 haul->triangle->others[haul->k1] == 0)
00462 {
00463 triangle.others[k1] = haul->triangle;
00464 haul->triangle->others[haul->k1] = ▵
00465 LASS_ASSERT(numBoundaryEdges_ >= 2);
00466 numBoundaryEdges_ -= 2;
00467 for (size_t s = 1; s <= 2; ++s)
00468 {
00469
00470 Triangle* other = haul->triangle;
00471 size_t k = s == 1 ? haul->k2 : haul->k1;
00472 const TPoint* const v =
00473 triangle.vertices[s == 1 ? k1 : k2];
00474 const TPoint* const otherV = other->vertices[k];
00475 LASS_ASSERT(*v == *otherV);
00476 if (v != otherV)
00477 {
00478 do
00479 {
00480 LASS_ASSERT(other->vertices[k] == otherV);
00481 other->vertices[k] = v;
00482 other = other->others[
00483 (k + (s == 1 ? 0 : 2)) % 3];
00484 k = other ? other->side(otherV) : 3;
00485 }
00486 while (other && k < 3);
00487 }
00488 }
00489 }
00490 }
00491 }
00492 }
00493 }
00494
00495
00496
00497
00498
00499 template <typename T, template <typename, typename, typename> class BHV, typename SH>
00500 void TriangleMesh3D<T, BHV, SH>::autoCrease(unsigned level)
00501 {
00502 const size_t numTriangles = triangles_.size();
00503 for (size_t i = 0; i < numTriangles; ++i)
00504 {
00505 Triangle& triangle = triangles_[i];
00506 for (size_t k1 = 2, k2 = 0; k2 < 3; k1 = k2++)
00507 {
00508 triangle.creaseLevel[k1] = 0;
00509 if (Triangle* other = triangle.others[k1])
00510 {
00511 const size_t otherK1 = other->side(triangle.vertices[k1]);
00512 const size_t otherK2 = (otherK1 + 2) % 3;
00513 LASS_ASSERT(otherK1 < 3 && otherK2 == other->side(triangle.vertices[k2]));
00514 const bool hasNormals =
00515 triangle.normals[k1] && triangle.normals[k2] &&
00516 other->normals[otherK1] && other->normals[otherK2];
00517 const bool isCrease = !hasNormals ||
00518 *triangle.normals[k1] != *other->normals[otherK1] ||
00519 *triangle.normals[k2] != *other->normals[otherK2];
00520 triangle.creaseLevel[k1] = isCrease ? level : 0;
00521 }
00522 }
00523 }
00524 }
00525
00526
00527
00528 template <typename T, template <typename, typename, typename> class BHV, typename SH>
00529 const Result TriangleMesh3D<T, BHV, SH>::intersect(const TRay& ray, TTriangleIterator& triangle,
00530 TReference t, TParam tMin, IntersectionContext* context) const
00531 {
00532 LASS_ASSERT(tree_.isEmpty() == triangles_.empty());
00533 const TTriangleIterator candidate = tree_.intersect(ray, t, tMin);
00534 if (candidate == triangles_.end())
00535 {
00536 return rNone;
00537 }
00538 triangle = candidate;
00539
00540 if (context)
00541 {
00542 TValue temp;
00543 const Result r = triangle->intersect(ray, temp, tMin, context);
00544 LASS_ASSERT(r == rOne && t == temp);
00545 }
00546
00547 return rOne;
00548 }
00549
00550
00551
00552 template <typename T, template <typename, typename, typename> class BHV, typename SH>
00553 const bool TriangleMesh3D<T, BHV, SH>::intersects(const TRay& ray, TParam tMin, TParam tMax) const
00554 {
00555 LASS_ASSERT(tree_.isEmpty() == triangles_.empty());
00556 return tree_.intersects(ray, tMin, tMax);
00557 }
00558
00559
00560
00561 template <typename T, template <typename, typename, typename> class BHV, typename SH>
00562 void TriangleMesh3D<T, BHV, SH>::swap(TSelf& other)
00563 {
00564 tree_.swap(other.tree_);
00565 triangles_.swap(other.trtriangles_ee_);
00566 vertices_.swap(other.vertices_);
00567 normals_.swap(other.normals_);
00568 uvs_.swap(other.uvs_);
00569 }
00570
00571
00572
00573
00574
00575 template <typename T, template <typename, typename, typename> class BHV, typename SH>
00576 const Result TriangleMesh3D<T, BHV, SH>::Triangle::intersect(const TRay& ray,
00577 TReference t, TParam tMin, IntersectionContext* context) const
00578 {
00579 LASS_ASSERT(vertices[0] && vertices[1] && vertices[2]);
00580 const TPoint point0 = *vertices[0];
00581 const TVector dPoint_dR = *vertices[1] - point0;
00582 const TVector dPoint_dS = *vertices[2] - point0;
00583
00584 TValue r, s;
00585 const Result hit = impl::intersectTriangle3D(
00586 point0, dPoint_dR, dPoint_dS, ray.support(), ray.direction(), r, s, t, tMin);
00587 if (hit != rOne)
00588 {
00589 return hit;
00590 }
00591
00592 if (context)
00593 {
00594 TUv dRs_dU(1, 0);
00595 TUv dRs_dV(0, 1);
00596 if (uvs[0])
00597 {
00598 LASS_ASSERT(uvs[1] && uvs[2]);
00599 const TUv uv0 = *uvs[0];
00600 const typename TUv::TVector dUv_dR = *uvs[1] - uv0;
00601 const typename TUv::TVector dUv_dS = *uvs[2] - uv0;
00602 context->uv = uv0 + r * dUv_dR + s * dUv_dS;
00603
00604 const TValue matrix[4] = { dUv_dR.x, dUv_dS.x, dUv_dR.y, dUv_dS.y };
00605 TValue solution[4] = { 1, 0, 0, 1 };
00606 num::impl::cramer2<TValue>(matrix, solution, solution + 4);
00607 dRs_dU = TUv(solution[0], solution[2]);
00608 dRs_dV = TUv(solution[1], solution[3]);
00609 context->dPoint_dU = dPoint_dR * dRs_dU.x + dPoint_dS * dRs_dU.y;
00610 context->dPoint_dV = dPoint_dR * dRs_dV.x + dPoint_dS * dRs_dV.y;
00611 }
00612 else
00613 {
00614 context->uv = TUv(r, s);
00615 context->dPoint_dU = dPoint_dR;
00616 context->dPoint_dV = dPoint_dS;
00617 }
00618
00619 context->geometricNormal = cross(dPoint_dR, dPoint_dS).normal();
00620 if (normals[0])
00621 {
00622 LASS_ASSERT(normals[1] && normals[2]);
00623 const TVector normal0 = *normals[0];
00624 const TVector dNormal_dR = *normals[1] - normal0;
00625 const TVector dNormal_dS = *normals[2] - normal0;
00626 context->normal = (normal0 + r * dNormal_dR + s * dNormal_dS).normal();
00627 context->dNormal_dU = dNormal_dR * dRs_dU.x + dNormal_dS * dRs_dU.y;
00628 context->dNormal_dV = dNormal_dR * dRs_dV.x + dNormal_dS * dRs_dV.y;
00629 }
00630 else
00631 {
00632 context->normal = context->geometricNormal;
00633 context->dNormal_dU = TVector();
00634 context->dNormal_dV = TVector();
00635 }
00636 }
00637 return rOne;
00638 }
00639
00640
00641
00642 template <typename T, template <typename, typename, typename> class BHV, typename SH> inline
00643 const size_t TriangleMesh3D<T, BHV, SH>::Triangle::side(const TPoint* vertex) const
00644 {
00645 return vertices[0] == vertex ? 0 : (vertices[1] == vertex ? 1 : (vertices[2] == vertex ? 2 : size_t(-1)));
00646 }
00647
00648
00649
00650
00651
00652 template <typename T, template <typename, typename, typename> class BHV, typename SH>
00653 template <typename IndexTriangleInputRange>
00654 void TriangleMesh3D<T, BHV, SH>::buildMesh(const IndexTriangleInputRange& triangles)
00655 {
00656 const std::size_t sizeVertices = vertices_.size();
00657 const std::size_t sizeNormals = normals_.size();
00658 const std::size_t sizeUvs = uvs_.size();
00659
00660 for (typename IndexTriangleInputRange::const_iterator i = triangles.begin(); i != triangles.end(); ++i)
00661 {
00662 TTriangle triangle;
00663 size_t numNormals = 0;
00664 size_t numUvs = 0;
00665 for (std::size_t k = 0; k < 3; ++k)
00666 {
00667 triangle.others[k] = 0;
00668 triangle.creaseLevel[k] = 0;
00669
00670 const std::size_t vertex = i->vertices[k];
00671 triangle.vertices[k] = &vertices_[LASS_ENFORCE_INDEX(vertex, sizeVertices)];
00672
00673 const std::size_t normal = i->normals[k];
00674 if (normal != IndexTriangle::null())
00675 {
00676 triangle.normals[k] = &normals_[LASS_ENFORCE_INDEX(normal, sizeNormals)];
00677 ++numNormals;
00678 }
00679 else
00680 {
00681 triangle.normals[k] = 0;
00682 }
00683
00684 const std::size_t uv = i->uvs[k];
00685 if (uv != IndexTriangle::null())
00686 {
00687 triangle.uvs[k] = &uvs_.begin()[LASS_ENFORCE_INDEX(uv, sizeUvs)];
00688 ++numUvs;
00689 }
00690 else
00691 {
00692 triangle.uvs[k] = 0;
00693 }
00694 }
00695
00696 if (!(numNormals == 0 || numNormals == 3))
00697 {
00698 LASS_THROW("Each triangle must have either zero or three normals vectors");
00699 }
00700 if (!(numUvs == 0 || numUvs == 3))
00701 {
00702 LASS_THROW("Each triangle must have either zero or three uv coordinates");
00703 }
00704
00705 triangles_.push_back(triangle);
00706 }
00707
00708 connectTriangles();
00709 tree_.reset(triangles_.begin(), triangles_.end());
00710 }
00711
00712
00713
00714 template <typename T, template <typename, typename, typename> class BHV, typename SH>
00715 void TriangleMesh3D<T, BHV, SH>::findVertexTriangles(TVertexTriangles& vertexTriangles) const
00716 {
00717 TVertexTriangles result(vertices_.size(), 0);
00718 const TPoint* const firstVertex = &vertices_[0];
00719 for (typename TTriangles::const_iterator i = triangles_.begin(); i != triangles_.end(); ++i)
00720 {
00721 const Triangle& triangle = *i;
00722 for (size_t k = 0; k < 3; ++k)
00723 {
00724 const size_t j = triangle.vertices[k] - firstVertex;
00725 LASS_ASSERT(j < result.size());
00726 result[j] = ▵
00727 }
00728 }
00729 vertexTriangles.swap(result);
00730 }
00731
00732
00733
00734 template <typename T, template <typename, typename, typename> class BHV, typename SH>
00735 void TriangleMesh3D<T, BHV, SH>::connectTriangles()
00736 {
00737 typedef std::vector<LogicalEdge> TEdges;
00738
00739 numBoundaryEdges_ = 0;
00740 const size_t numTriangles = triangles_.size();
00741 if (numTriangles == 0)
00742 {
00743 return;
00744 }
00745
00746
00747
00748 TEdges edges;
00749 edges.reserve(3 * numTriangles);
00750 for (size_t i = 0; i < numTriangles; ++i)
00751 {
00752 Triangle& triangle = triangles_[i];
00753 for (std::size_t k1 = 2, k2 = 0; k2 < 3; k1 = k2++)
00754 {
00755 edges.push_back(LogicalEdge(
00756 &triangle, triangle.vertices[k1], triangle.vertices[k2]));
00757 }
00758 }
00759 std::sort(edges.begin(), edges.end());
00760
00761
00762
00763 for (size_t i = 0; i < numTriangles; ++i)
00764 {
00765 Triangle& triangle = triangles_[i];
00766 for (std::size_t k1 = 2, k2 = 0; k2 < 3; k1 = k2++)
00767 {
00768 const LogicalEdge bait(
00769 0, triangle.vertices[k2], triangle.vertices[k1]);
00770 const typename TEdges::const_iterator haul = std::lower_bound(
00771 edges.begin(), edges.end(), bait);
00772 if (haul != edges.end() && !(bait < *haul))
00773 {
00774 triangle.others[k1] = haul->triangle;
00775 }
00776 else
00777 {
00778 triangle.others[k1] = 0;
00779 ++numBoundaryEdges_;
00780 }
00781 }
00782 }
00783 }
00784
00785
00786
00787 template <typename T, template <typename, typename, typename> class BHV, typename SH>
00788 void TriangleMesh3D<T, BHV, SH>::findVertexRing(
00789 const TPoint& vertex, const Triangle* vertexTriangle, TVertexRing& ring,
00790 TVertexRing& creases, TNormalRing& normals, TUvRing& uvs) const
00791 {
00792 ring.resize(0);
00793 creases.resize(0);
00794 normals.resize(0);
00795 uvs.resize(0);
00796
00797 bool hasUvRing = true;
00798 const TUv* vertexUv = 0;
00799 const Triangle* triangle = vertexTriangle;
00800 do
00801 {
00802 const size_t k = triangle->side(&vertex);
00803 LASS_ASSERT(k < 3);
00804 const size_t kCcw = (k + 2) % 3;
00805 const TPoint& neighbour = *triangle->vertices[kCcw];
00806 const Triangle* const other = triangle->others[kCcw];
00807 if (triangle->creaseLevel[kCcw] > 0 || !other)
00808 {
00809
00810 creases.push_back(neighbour);
00811 }
00812
00813 if (!vertexUv)
00814 {
00815 vertexUv = triangle->uvs[k];
00816 }
00817 hasUvRing &= vertexUv != 0 && vertexUv == triangle->uvs[k];
00818 if (hasUvRing)
00819 {
00820 LASS_ASSERT(triangle->uvs[kCcw]);
00821 uvs.push_back(*triangle->uvs[kCcw]);
00822 }
00823
00824 if (!other)
00825 {
00826
00827
00828
00829 const Triangle* triangle2 = vertexTriangle;
00830 const TPoint* neighbour2 = 0;
00831 while (triangle2)
00832 {
00833 const size_t k = triangle2->side(&vertex);
00834 LASS_ASSERT(k < 3);
00835 const size_t kCw = (k + 1) % 3;
00836 neighbour2 = triangle2->vertices[kCw];
00837 const Triangle* other2 = triangle2->others[k];
00838 if (triangle2->creaseLevel[kCw] > 0 || !other2)
00839 {
00840
00841 creases.push_back(*neighbour2);
00842 }
00843 triangle2 = other2;
00844 }
00845 ring.resize(1, *neighbour2);
00846 hasUvRing = false;
00847 }
00848 ring.push_back(neighbour);
00849 triangle = other;
00850 }
00851 while (triangle && triangle != vertexTriangle);
00852
00853 if (!hasUvRing)
00854 {
00855 uvs.resize(0);
00856 }
00857
00858 }
00859
00860
00861
00862
00863
00864
00865 template <typename T, template <typename, typename, typename> class BHV, typename SH>
00866 void TriangleMesh3D<T, BHV, SH>::subdivide()
00867 {
00868 if (triangles_.empty())
00869 {
00870 return;
00871 }
00872
00873 const size_t numTriangles = triangles_.size();
00874 const size_t numVertices = vertices_.size();
00875 const size_t numUvs = uvs_.size();
00876 const size_t numNormals = normals_.size();
00877 LASS_ASSERT((3 * numTriangles + numBoundaryEdges_) % 2 == 0);
00878 const size_t numOddVertices = (3 * numTriangles + numBoundaryEdges_) / 2;
00879
00880 TTriangles newTriangles(4 * numTriangles);
00881 TVertices newVertices = vertices_;
00882 TNormals newNormals = normals_;
00883 TUvs newUvs = uvs_;
00884 newVertices.reserve(numVertices + numOddVertices);
00885 newNormals.reserve(numNormals + 3 * numTriangles);
00886 newUvs.reserve(numUvs + 3 * numTriangles);
00887
00888 const Triangle* const firstTriangle = &triangles_[0];
00889 const TPoint* const firstVertex = &vertices_[0];
00890 const TVector* const firstNormal = &normals_[0];
00891 const TUv* const firstUv = &uvs_[0];
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907 for (size_t i = 0; i < numTriangles; ++i)
00908 {
00909 const Triangle& triangle = triangles_[i];
00910 Triangle* const newTris = &newTriangles[4 * i];
00911 Triangle& oddTriangle = newTris[3];
00912
00913
00914
00915 for (size_t k0 = 2, k1 = 0; k1 < 3; k0 = k1++)
00916 {
00917 const Triangle* const other = triangle.others[k0];
00918 Triangle* const oddOther = other ? &newTriangles[4 * (other - firstTriangle) + 3] : 0;
00919 const size_t h0 = other ? other->side(triangle.vertices[k1]) : size_t(-1);
00920 const size_t h1 = other ? other->side(triangle.vertices[k0]) : size_t(-1);
00921 LASS_ASSERT(h0 < 3 && h1 == (h0 + 1) % 3 || other == 0);
00922
00923 if (!oddTriangle.vertices[k0])
00924 {
00925 LASS_ASSERT(newVertices.size() < newVertices.capacity());
00926 newVertices.push_back(TPoint(.5 * (triangle.vertices[k0]->position() + triangle.vertices[k1]->position())));
00927 oddTriangle.vertices[k0] = &newVertices.back();
00928 if (other)
00929 {
00930 oddOther->vertices[h0] = &newVertices.back();
00931 }
00932 }
00933 if (triangle.normals[k0] && !oddTriangle.normals[k0])
00934 {
00935 LASS_ASSERT(triangle.normals[k1]);
00936 LASS_ASSERT(newNormals.size() < newNormals.capacity());
00937 newNormals.push_back(.5 * (*triangle.normals[k0] + *triangle.normals[k1]));
00938 oddTriangle.normals[k0] = &newNormals.back();
00939 if (other && triangle.normals[k0] == other->normals[h1] && triangle.normals[k1] == other->normals[h0])
00940 {
00941 oddOther->normals[h0] = &newNormals.back();
00942 }
00943 }
00944 if (triangle.uvs[k0] && !oddTriangle.uvs[k0])
00945 {
00946 LASS_ASSERT(newUvs.size() < newUvs.capacity());
00947 LASS_ASSERT(triangle.uvs[k1]);
00948 newUvs.push_back(TUv(.5 * (triangle.uvs[k0]->position() + triangle.uvs[k1]->position())));
00949 oddTriangle.uvs[k0] = &newUvs.back();
00950 if (other && triangle.uvs[k0] == other->uvs[h1] && triangle.uvs[k1] == other->uvs[h0])
00951 {
00952 oddOther->uvs[h0] = &newUvs.back();
00953 }
00954 }
00955 oddTriangle.others[k0] = &newTris[k1];
00956 oddTriangle.creaseLevel[k0] = 0;
00957 }
00958
00959
00960
00961 for (size_t k0 = 0, k1 = 1, k2 = 2; k0 < 3; k1 = k2, k2 = k0, ++k0)
00962 {
00963 Triangle& newTriangle = newTris[k0];
00964 newTriangle.vertices[k0] = &newVertices[triangle.vertices[k0] - firstVertex];
00965 newTriangle.vertices[k1] = oddTriangle.vertices[k0];
00966 newTriangle.vertices[k2] = oddTriangle.vertices[k2];
00967 newTriangle.normals[k0] = triangle.normals[k0] ? &newNormals[triangle.normals[k0] - firstNormal] : 0;
00968 newTriangle.normals[k1] = oddTriangle.normals[k0];
00969 newTriangle.normals[k2] = oddTriangle.normals[k2];
00970 newTriangle.uvs[k0] = triangle.uvs[k0] ? &newUvs[triangle.uvs[k0] - firstUv] : 0;
00971 newTriangle.uvs[k1] = oddTriangle.uvs[k0];
00972 newTriangle.uvs[k2] = oddTriangle.uvs[k2];
00973 if (const Triangle* other0 = triangle.others[k0])
00974 {
00975 const size_t j = other0 - firstTriangle;
00976 const size_t h = other0->side(triangle.vertices[k0]);
00977 LASS_ASSERT(h < 3);
00978 Triangle& newOther = newTriangles[4 * j + h];
00979 LASS_ASSERT(newOther.others[(h + 2) % 3] == 0 || newOther.others[(h + 2) % 3] == &newTriangle);
00980 newTriangle.others[k0] = &newOther;
00981 }
00982 newTriangle.others[k1] = &oddTriangle;
00983 if (const Triangle* other2 = triangle.others[k2])
00984 {
00985 const size_t j = other2 - firstTriangle;
00986 const size_t h = other2->side(triangle.vertices[k0]);
00987 LASS_ASSERT(h < 3);
00988 Triangle& newOther = newTriangles[4 * j + h];
00989 LASS_ASSERT(newOther.others[h] == 0 || newOther.others[h] == &newTriangle);
00990 newTriangle.others[k2] = &newOther;
00991 }
00992 newTriangle.creaseLevel[k0] = triangle.creaseLevel[k0];
00993 newTriangle.creaseLevel[k1] = 0;
00994 newTriangle.creaseLevel[k2] = triangle.creaseLevel[k2];
00995 }
00996 }
00997
00998 triangles_.swap(newTriangles);
00999 vertices_.swap(newVertices);
01000 normals_.swap(newNormals);
01001 uvs_.swap(newUvs);
01002 tree_.reset();
01003 numBoundaryEdges_ *= 2;
01004 }
01005
01006
01007
01008
01009
01010
01011
01012 }
01013
01014 }
01015
01016 #endif
01017
01018