diff --git a/vcg/complex/algorithms/clip.h b/vcg/complex/algorithms/clip.h index 8741eb69..e15a93c0 100644 --- a/vcg/complex/algorithms/clip.h +++ b/vcg/complex/algorithms/clip.h @@ -8,7 +8,7 @@ * \ * * All rights reserved. * * * -* This program is free software; you can redistribute it and/or modify * +* This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * @@ -21,30 +21,11 @@ * * ****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ - -****************************************************************************/ - #ifndef __VCGLIB_TRI_CLIP #define __VCGLIB_TRI_CLIP +#include +#include -#include - -#ifdef _WIN32 - #ifndef __MINGW32__ - #include - #define STDEXT stdext - #else - #include - #define STDEXT __gnu_cxx - #endif -#else - #include - #define STDEXT __gnu_cxx -#endif namespace vcg { namespace tri @@ -103,33 +84,33 @@ class TriMeshClipper { public: - typedef TriMeshClipper ClassType; - typedef TRIMESHTYPE TriMeshType; - typedef typename TriMeshType::FaceType FaceType; - typedef typename FaceType::VertexType VertexType; - typedef typename VertexType::CoordType CoordType; - typedef typename CoordType::ScalarType ScalarType; + typedef TriMeshClipper ClassType; + typedef TRIMESHTYPE TriMeshType; + typedef typename TriMeshType::FaceType FaceType; + typedef typename FaceType::VertexType VertexType; + typedef typename VertexType::CoordType CoordType; + typedef typename CoordType::ScalarType ScalarType; - /* - static inline void Box(const Box3 & b, VERTEXINTEPOLATOR & vInterp, TriMeshType & m); + /* + static inline void Box(const Box3 & b, VERTEXINTEPOLATOR & vInterp, TriMeshType & m); - Clip mesh "m" against an axis aligned box (in place version); + Clip mesh "m" against an axis aligned box (in place version); - Notes: - 1) faces marked as deleted are skipped; - 2) faces completely outside box are marked as deleted; - 3) faces completely inside box are left unchanged; - 4) faces intersecting box's sides are marked as deleted: - they are replaced with proper tesselation; new vertices and faces - are created, so reallocation could occour; previously saved pointers - could not to be valid anymore, thus they should be updated; - 5) vInterp functor must implement a n operator with signature - void operator () (const VERTEX & v0, const VERTEX & v1, const VERTEX & v2, const Scalar & a, const Scalar & b, VERTEX & r); - its semantic is to intepolate vertex attribute across triangle; a typical implementation is; - r.P() = v0.P() + a * (v1.P() - v0.P()) + b * (v2.P() - v0.P()); // interpolate position - r.N() = v0.N() + a * (v1.N() - v0.N()) + b * (v2.N() - v0.N()); // interpolate normal - ... // interpolate other vertex attributes - */ + Notes: + 1) faces marked as deleted are skipped; + 2) faces completely outside box are marked as deleted; + 3) faces completely inside box are left unchanged; + 4) faces intersecting box's sides are marked as deleted: + they are replaced with proper tesselation; new vertices and faces + are created, so reallocation could occour; previously saved pointers + could not to be valid anymore, thus they should be updated; + 5) vInterp functor must implement a n operator with signature + void operator () (const VERTEX & v0, const VERTEX & v1, const VERTEX & v2, const Scalar & a, const Scalar & b, VERTEX & r); + its semantic is to intepolate vertex attribute across triangle; a typical implementation is; + r.P() = v0.P() + a * (v1.P() - v0.P()) + b * (v2.P() - v0.P()); // interpolate position + r.N() = v0.N() + a * (v1.N() - v0.N()) + b * (v2.N() - v0.N()); // interpolate normal + ... // interpolate other vertex attributes + */ template class VertexClipInfo { @@ -160,16 +141,16 @@ public: unsigned int idx; }; - template - static inline void Box(const Box3 & b, VERTEXINTEPOLATOR & vInterp, TriMeshType & m) - { - std::vector facesToDelete; - ClassType::Box(b, vInterp, m, facesToDelete); - for (size_t i=0; i + static inline void Box(const Box3 & b, VERTEXINTEPOLATOR & vInterp, TriMeshType & m) + { + std::vector facesToDelete; + ClassType::Box(b, vInterp, m, facesToDelete); + for (size_t i=0; i UIntHMap; + typedef std::unordered_map UIntHMap; typedef typename UIntHMap::iterator UIntHMap_i; typedef typename UIntHMap::value_type UIntHMap_v; - typedef STDEXT::hash_map EdgeMap; + typedef std::unordered_map EdgeMap; typedef typename EdgeMap::iterator EdgeMap_i; typedef typename EdgeMap::value_type EdgeMap_v; typedef typename TriMeshType::FaceIterator FaceIterator; - template - static inline void Box(const Box3 & b, VERTEXINTEPOLATOR & vInterp, TriMeshType & m, FACEINDEXCONTAINER & facesToDelete) - { - if (m.fn <= 0) - { - return; - } + template + static inline void Box(const Box3 & b, VERTEXINTEPOLATOR & vInterp, TriMeshType & m, FACEINDEXCONTAINER & facesToDelete) + { + if (m.fn <= 0) + { + return; + } - EdgeMap edges; + EdgeMap edges; VertexClipInfoVec vInfos; - TriangleInfoVec tInfos; + TriangleInfoVec tInfos; - CoordType vTriangle[4]; - CoordType vClipped[64]; + CoordType vTriangle[4]; + CoordType vClipped[64]; - CoordType pvP0[64]; - CoordType pvP1[64]; + CoordType pvP0[64]; + CoordType pvP1[64]; - unsigned int numDeletedTris = 0; - unsigned int numTriangles = 0; - unsigned int numVertices = 0; + unsigned int numDeletedTris = 0; + unsigned int numTriangles = 0; + unsigned int numVertices = 0; - unsigned int vIdx = (unsigned int)(m.vn); - unsigned int tIdx = (unsigned int)(m.fn); + unsigned int vIdx = (unsigned int)(m.vn); + unsigned int tIdx = (unsigned int)(m.fn); - ScalarType boxOffsets[6]; + ScalarType boxOffsets[6]; - boxOffsets[0] = b.min[0]; - boxOffsets[1] = -b.max[0]; - boxOffsets[2] = b.min[1]; - boxOffsets[3] = -b.max[1]; - boxOffsets[4] = b.min[2]; - boxOffsets[5] = -b.max[2]; + boxOffsets[0] = b.min[0]; + boxOffsets[1] = -b.max[0]; + boxOffsets[2] = b.min[1]; + boxOffsets[3] = -b.max[1]; + boxOffsets[4] = b.min[2]; + boxOffsets[5] = -b.max[2]; - UIntHMap emptyMap; - EdgeIntersections emptyIsects; + UIntHMap emptyMap; + EdgeIntersections emptyIsects; - const ScalarType eps = (ScalarType)(1e-6); + const ScalarType eps = (ScalarType)(1e-6); - for (FaceIterator it=m.face.begin(); it!=m.face.end(); ++it) - { - if ((*it).IsD()) - { - continue; - } + for (FaceIterator it=m.face.begin(); it!=m.face.end(); ++it) + { + if ((*it).IsD()) + { + continue; + } - unsigned int cc[3]; + unsigned int cc[3]; - cc[0] = ClassType::BoxClipCode(boxOffsets, (*it).V(0)->P()); - cc[1] = ClassType::BoxClipCode(boxOffsets, (*it).V(1)->P()); - cc[2] = ClassType::BoxClipCode(boxOffsets, (*it).V(2)->P()); + cc[0] = ClassType::BoxClipCode(boxOffsets, (*it).V(0)->P()); + cc[1] = ClassType::BoxClipCode(boxOffsets, (*it).V(1)->P()); + cc[2] = ClassType::BoxClipCode(boxOffsets, (*it).V(2)->P()); - if ((cc[0] | cc[1] | cc[2]) == 0) - { - continue; - } + if ((cc[0] | cc[1] | cc[2]) == 0) + { + continue; + } - const unsigned int refT = (unsigned int)(std::distance(m.face.begin(), it)); + const unsigned int refT = (unsigned int)(std::distance(m.face.begin(), it)); - if ((cc[0] & cc[1] & cc[2]) != 0) - { - facesToDelete.push_back(refT); - (*it).SetD(); - numDeletedTris++; - continue; - } + if ((cc[0] & cc[1] & cc[2]) != 0) + { + facesToDelete.push_back(refT); + (*it).SetD(); + numDeletedTris++; + continue; + } - facesToDelete.push_back(refT); + facesToDelete.push_back(refT); - vTriangle[0] = (*it).V(0)->P(); - vTriangle[1] = (*it).V(1)->P(); - vTriangle[2] = (*it).V(2)->P(); - vTriangle[3] = (*it).V(0)->P(); + vTriangle[0] = (*it).V(0)->P(); + vTriangle[1] = (*it).V(1)->P(); + vTriangle[2] = (*it).V(2)->P(); + vTriangle[3] = (*it).V(0)->P(); - unsigned int n, n0, n1; + unsigned int n, n0, n1; - ClipPolygonLine(0, b.min[0], vTriangle, 4, pvP1, n1); - ClipPolygonLine(1, b.max[0], pvP1, n1, pvP0, n0); + ClipPolygonLine(0, b.min[0], vTriangle, 4, pvP1, n1); + ClipPolygonLine(1, b.max[0], pvP1, n1, pvP0, n0); - ClipPolygonLine(2, b.min[1], pvP0, n0, pvP1, n1); - ClipPolygonLine(3, b.max[1], pvP1, n1, pvP0, n0); + ClipPolygonLine(2, b.min[1], pvP0, n0, pvP1, n1); + ClipPolygonLine(3, b.max[1], pvP1, n1, pvP0, n0); - ClipPolygonLine(4, b.min[2], pvP0, n0, pvP1, n1); - ClipPolygonLine(5, b.max[2], pvP1, n1, vClipped, n); + ClipPolygonLine(4, b.min[2], pvP0, n0, pvP1, n1); + ClipPolygonLine(5, b.max[2], pvP1, n1, vClipped, n); - assert(n < 64); + assert(n < 64); - unsigned int firstV, lastV; + unsigned int firstV, lastV; - if (n > 2) - { - if (vClipped[0] == vClipped[n - 1]) - { - n--; - } + if (n > 2) + { + if (vClipped[0] == vClipped[n - 1]) + { + n--; + } - const CoordType vU = vTriangle[1] - vTriangle[0]; - const CoordType vV = vTriangle[2] - vTriangle[0]; + const CoordType vU = vTriangle[1] - vTriangle[0]; + const CoordType vV = vTriangle[2] - vTriangle[0]; - const ScalarType tArea = (vU ^ vV).SquaredNorm(); - if (tArea < eps) - { - continue; - } + const ScalarType tArea = (vU ^ vV).SquaredNorm(); + if (tArea < eps) + { + continue; + } - unsigned int tvidx[3]; - tvidx[0] = (*it).V(0) - &(*(m.vert.begin())); - tvidx[1] = (*it).V(1) - &(*(m.vert.begin())); - tvidx[2] = (*it).V(2) - &(*(m.vert.begin())); + unsigned int tvidx[3]; + tvidx[0] = (*it).V(0) - &(*(m.vert.begin())); + tvidx[1] = (*it).V(1) - &(*(m.vert.begin())); + tvidx[2] = (*it).V(2) - &(*(m.vert.begin())); - numTriangles += n - 2; + numTriangles += n - 2; // size_t vBegin = vInfos.size(); VertexClipInfo vnfo; - TriangleInfo tnfo; + TriangleInfo tnfo; - unsigned int vmin[3]; - unsigned int vmax[3]; + unsigned int vmin[3]; + unsigned int vmax[3]; - if (tvidx[0] < tvidx[1]) - { - vmin[0] = tvidx[0]; - vmax[0] = tvidx[1]; - } - else - { - vmin[0] = tvidx[1]; - vmax[0] = tvidx[0]; - } + if (tvidx[0] < tvidx[1]) + { + vmin[0] = tvidx[0]; + vmax[0] = tvidx[1]; + } + else + { + vmin[0] = tvidx[1]; + vmax[0] = tvidx[0]; + } - if (tvidx[0] < tvidx[2]) - { - vmin[1] = tvidx[0]; - vmax[1] = tvidx[2]; - } - else - { - vmin[1] = tvidx[2]; - vmax[1] = tvidx[0]; - } + if (tvidx[0] < tvidx[2]) + { + vmin[1] = tvidx[0]; + vmax[1] = tvidx[2]; + } + else + { + vmin[1] = tvidx[2]; + vmax[1] = tvidx[0]; + } - if (tvidx[1] < tvidx[2]) - { - vmin[2] = tvidx[1]; - vmax[2] = tvidx[2]; - } - else - { - vmin[2] = tvidx[2]; - vmax[2] = tvidx[1]; - } + if (tvidx[1] < tvidx[2]) + { + vmin[2] = tvidx[1]; + vmax[2] = tvidx[2]; + } + else + { + vmin[2] = tvidx[2]; + vmax[2] = tvidx[1]; + } - for (unsigned int i=0; i mi = edges.insert(std::make_pair(vmin[1], emptyMap)); - std::pair hi = (*(mi.first)).second.insert(std::make_pair(vmax[1], emptyIsects)); - bool found = false; - for (unsigned int s=0; s<(*(hi.first)).second.n; ++s) - { - if (vClipped[i] == (*(hi.first)).second.isects[s].p) - { - found = true; - vnfo.idx = (*(hi.first)).second.isects[s].idx; - break; - } - } - if (!found) - { - vnfo.idx = vIdx++; - numVertices++; - vInfos.push_back(vnfo); + if (vClipped[i] == vTriangle[0]) + { + vnfo.idx = tvidx[0]; + } + else if (vClipped[i] == vTriangle[1]) + { + vnfo.idx = tvidx[1]; + } + else if (vClipped[i] == vTriangle[2]) + { + vnfo.idx = tvidx[2]; + } + else if (vnfo.fV < eps) + { + std::pair mi = edges.insert(std::make_pair(vmin[1], emptyMap)); + std::pair hi = (*(mi.first)).second.insert(std::make_pair(vmax[1], emptyIsects)); + bool found = false; + for (unsigned int s=0; s<(*(hi.first)).second.n; ++s) + { + if (vClipped[i] == (*(hi.first)).second.isects[s].p) + { + found = true; + vnfo.idx = (*(hi.first)).second.isects[s].idx; + break; + } + } + if (!found) + { + vnfo.idx = vIdx++; + numVertices++; + vInfos.push_back(vnfo); - (*(hi.first)).second.isects[(*(hi.first)).second.n].p = vClipped[i]; - (*(hi.first)).second.isects[(*(hi.first)).second.n].idx = vnfo.idx; - (*(hi.first)).second.n++; - } - } - else if (vnfo.fU < eps) - { - std::pair mi = edges.insert(std::make_pair(vmin[0], emptyMap)); - std::pair hi = (*(mi.first)).second.insert(std::make_pair(vmax[0], emptyIsects)); - bool found = false; - for (unsigned int s=0; s<(*(hi.first)).second.n; ++s) - { - if (vClipped[i] == (*(hi.first)).second.isects[s].p) - { - found = true; - vnfo.idx = (*(hi.first)).second.isects[s].idx; - break; - } - } - if (!found) - { - vnfo.idx = vIdx++; - numVertices++; - vInfos.push_back(vnfo); + (*(hi.first)).second.isects[(*(hi.first)).second.n].p = vClipped[i]; + (*(hi.first)).second.isects[(*(hi.first)).second.n].idx = vnfo.idx; + (*(hi.first)).second.n++; + } + } + else if (vnfo.fU < eps) + { + std::pair mi = edges.insert(std::make_pair(vmin[0], emptyMap)); + std::pair hi = (*(mi.first)).second.insert(std::make_pair(vmax[0], emptyIsects)); + bool found = false; + for (unsigned int s=0; s<(*(hi.first)).second.n; ++s) + { + if (vClipped[i] == (*(hi.first)).second.isects[s].p) + { + found = true; + vnfo.idx = (*(hi.first)).second.isects[s].idx; + break; + } + } + if (!found) + { + vnfo.idx = vIdx++; + numVertices++; + vInfos.push_back(vnfo); - (*(hi.first)).second.isects[(*(hi.first)).second.n].p = vClipped[i]; - (*(hi.first)).second.isects[(*(hi.first)).second.n].idx = vnfo.idx; - (*(hi.first)).second.n++; - } - } - else if ((vnfo.fU + vnfo.fV) >= ((ScalarType)(1.0 - 1e-5))) - { - std::pair mi = edges.insert(std::make_pair(vmin[2], emptyMap)); - std::pair hi = (*(mi.first)).second.insert(std::make_pair(vmax[2], emptyIsects)); - bool found = false; - for (unsigned int s=0; s<(*(hi.first)).second.n; ++s) - { - if (vClipped[i] == (*(hi.first)).second.isects[s].p) - { - found = true; - vnfo.idx = (*(hi.first)).second.isects[s].idx; - break; - } - } - if (!found) - { - vnfo.idx = vIdx++; - numVertices++; - vInfos.push_back(vnfo); + (*(hi.first)).second.isects[(*(hi.first)).second.n].p = vClipped[i]; + (*(hi.first)).second.isects[(*(hi.first)).second.n].idx = vnfo.idx; + (*(hi.first)).second.n++; + } + } + else if ((vnfo.fU + vnfo.fV) >= ((ScalarType)(1.0 - 1e-5))) + { + std::pair mi = edges.insert(std::make_pair(vmin[2], emptyMap)); + std::pair hi = (*(mi.first)).second.insert(std::make_pair(vmax[2], emptyIsects)); + bool found = false; + for (unsigned int s=0; s<(*(hi.first)).second.n; ++s) + { + if (vClipped[i] == (*(hi.first)).second.isects[s].p) + { + found = true; + vnfo.idx = (*(hi.first)).second.isects[s].idx; + break; + } + } + if (!found) + { + vnfo.idx = vIdx++; + numVertices++; + vInfos.push_back(vnfo); - (*(hi.first)).second.isects[(*(hi.first)).second.n].p = vClipped[i]; - (*(hi.first)).second.isects[(*(hi.first)).second.n].idx = vnfo.idx; - (*(hi.first)).second.n++; - } - } - else - { - vnfo.idx = vIdx++; - numVertices++; - vInfos.push_back(vnfo); - } + (*(hi.first)).second.isects[(*(hi.first)).second.n].p = vClipped[i]; + (*(hi.first)).second.isects[(*(hi.first)).second.n].idx = vnfo.idx; + (*(hi.first)).second.n++; + } + } + else + { + vnfo.idx = vIdx++; + numVertices++; + vInfos.push_back(vnfo); + } - if (i == 0) - { - firstV = vnfo.idx; - } + if (i == 0) + { + firstV = vnfo.idx; + } - if (i > 1) - { - tnfo.idx = tIdx++; - tnfo.v[0] = firstV; - tnfo.v[1] = lastV; - tnfo.v[2] = vnfo.idx; + if (i > 1) + { + tnfo.idx = tIdx++; + tnfo.v[0] = firstV; + tnfo.v[1] = lastV; + tnfo.v[2] = vnfo.idx; - tInfos.push_back(tnfo); - } + tInfos.push_back(tnfo); + } - lastV = vnfo.idx; - } - } - } + lastV = vnfo.idx; + } + } + } - if (numTriangles == 0) - { - return; - } + if (numTriangles == 0) + { + return; + } - const unsigned int vSize = (unsigned int)(m.vn); - const unsigned int tSize = (unsigned int)(m.fn); + const unsigned int vSize = (unsigned int)(m.vn); + const unsigned int tSize = (unsigned int)(m.fn); - typedef Allocator TriMeshAllocatorType; + typedef Allocator TriMeshAllocatorType; - TriMeshAllocatorType::AddVertices(m, numVertices); - TriMeshAllocatorType::AddFaces(m, numTriangles); + TriMeshAllocatorType::AddVertices(m, numVertices); + TriMeshAllocatorType::AddFaces(m, numTriangles); - unsigned int j = vSize; - for (size_t i=0; i= vSize) - { - const unsigned int tref = vInfos[i].tref; - vInterp(*(m.face[tref].V(0)), *(m.face[tref].V(1)), *(m.face[tref].V(2)), vInfos[i].fV, vInfos[i].fU, m.vert[j]); - j++; - } - } + unsigned int j = vSize; + for (size_t i=0; i= vSize) + { + const unsigned int tref = vInfos[i].tref; + vInterp(*(m.face[tref].V(0)), *(m.face[tref].V(1)), *(m.face[tref].V(2)), vInfos[i].fV, vInfos[i].fU, m.vert[j]); + j++; + } + } - j = tSize; - for (size_t i=0; i & b, VERTEXINTEPOLATOR & vInterp, const TriMeshType & m, TriMeshType & r); + /* + static inline void Box(const Box3 & b, VERTEXINTEPOLATOR & vInterp, const TriMeshType & m, TriMeshType & r); - Clip mesh "m" against an axis aligned box and put resulting data in mesh "r" (out of place version); + Clip mesh "m" against an axis aligned box and put resulting data in mesh "r" (out of place version); - Notes: - 1) input mesh is not modified; - 2) faces marked as deleted are skipped; - 3) vInterp functor must implement a n operator with signature - void operator () (const VERTEX & v0, const VERTEX & v1, const VERTEX & v2, const Scalar & a, const Scalar & b, VERTEX & r); - its semantic is to intepolate vertex attribute across triangle; a typical implementation is; - r.P() = v0.P() + a * (v1.P() - v0.P()) + b * (v2.P() - v0.P()); // interpolate position - r.N() = v0.N() + a * (v1.N() - v0.N()) + b * (v2.N() - v0.N()); // interpolate normal - ... // interpolate other vertex attributes - */ + Notes: + 1) input mesh is not modified; + 2) faces marked as deleted are skipped; + 3) vInterp functor must implement a n operator with signature + void operator () (const VERTEX & v0, const VERTEX & v1, const VERTEX & v2, const Scalar & a, const Scalar & b, VERTEX & r); + its semantic is to intepolate vertex attribute across triangle; a typical implementation is; + r.P() = v0.P() + a * (v1.P() - v0.P()) + b * (v2.P() - v0.P()); // interpolate position + r.N() = v0.N() + a * (v1.N() - v0.N()) + b * (v2.N() - v0.N()); // interpolate normal + ... // interpolate other vertex attributes + */ - template - static inline void Box(const Box3 & b, VERTEXINTEPOLATOR & vInterp, const TriMeshType & m, TriMeshType & r) - { - r.Clear(); + template + static inline void Box(const Box3 & b, VERTEXINTEPOLATOR & vInterp, const TriMeshType & m, TriMeshType & r) + { + r.Clear(); - if (m.fn <= 0) - { - return; - } + if (m.fn <= 0) + { + return; + } class VertexClipInfo - { - public: + { + public: typedef VertexClipInfo ClassType; - ScalarType fU; - ScalarType fV; - unsigned int idx; - unsigned int tref; - }; + ScalarType fU; + ScalarType fV; + unsigned int idx; + unsigned int tref; + }; typedef std::vector VertexClipInfoVec; - class TriangleInfo - { - public: - typedef TriangleInfo ClassType; + class TriangleInfo + { + public: + typedef TriangleInfo ClassType; - unsigned int v[3]; - unsigned int idx; - }; + unsigned int v[3]; + unsigned int idx; + }; - typedef std::vector TriangleInfoVec; + typedef std::vector TriangleInfoVec; - class EdgeIsect - { - public: - CoordType p; - unsigned int idx; - }; + class EdgeIsect + { + public: + CoordType p; + unsigned int idx; + }; - class EdgeIntersections - { - public: - unsigned int n; - EdgeIsect isects[6]; + class EdgeIntersections + { + public: + unsigned int n; + EdgeIsect isects[6]; - EdgeIntersections(void) - { - this->n = 0; - } - }; + EdgeIntersections(void) + { + this->n = 0; + } + }; - typedef STDEXT::hash_map UIntHMap; - typedef typename UIntHMap::iterator UIntHMap_i; - typedef typename UIntHMap::value_type UIntHMap_v; + typedef std::unordered_map UIntHMap; + typedef typename UIntHMap::iterator UIntHMap_i; + typedef typename UIntHMap::value_type UIntHMap_v; - typedef STDEXT::hash_map EdgeMap; - typedef typename EdgeMap::iterator EdgeMap_i; - typedef typename EdgeMap::value_type EdgeMap_v; + typedef std::unordered_map EdgeMap; + typedef typename EdgeMap::iterator EdgeMap_i; + typedef typename EdgeMap::value_type EdgeMap_v; - typedef STDEXT::hash_map UIHMap; - typedef typename UIHMap::iterator UIHMap_i; + typedef std::unordered_map UIHMap; + typedef typename UIHMap::iterator UIHMap_i; - typedef typename TriMeshType::ConstFaceIterator ConstFaceIterator; + typedef typename TriMeshType::ConstFaceIterator ConstFaceIterator; - UIHMap origVertsMap; - EdgeMap edges; + UIHMap origVertsMap; + EdgeMap edges; VertexClipInfoVec vInfos; - TriangleInfoVec tInfos; + TriangleInfoVec tInfos; - CoordType vTriangle[4]; - CoordType vClipped[64]; + CoordType vTriangle[4]; + CoordType vClipped[64]; - CoordType pvP0[64]; - CoordType pvP1[64]; + CoordType pvP0[64]; + CoordType pvP1[64]; - unsigned int numDeletedTris = 0; - unsigned int numTriangles = 0; - unsigned int numVertices = 0; + unsigned int numDeletedTris = 0; + unsigned int numTriangles = 0; + unsigned int numVertices = 0; - unsigned int vIdx = 0; - unsigned int tIdx = 0; + unsigned int vIdx = 0; + unsigned int tIdx = 0; - ScalarType boxOffsets[6]; + ScalarType boxOffsets[6]; - boxOffsets[0] = b.min[0]; - boxOffsets[1] = -b.max[0]; - boxOffsets[2] = b.min[1]; - boxOffsets[3] = -b.max[1]; - boxOffsets[4] = b.min[2]; - boxOffsets[5] = -b.max[2]; + boxOffsets[0] = b.min[0]; + boxOffsets[1] = -b.max[0]; + boxOffsets[2] = b.min[1]; + boxOffsets[3] = -b.max[1]; + boxOffsets[4] = b.min[2]; + boxOffsets[5] = -b.max[2]; - UIntHMap emptyMap; - EdgeIntersections emptyIsects; + UIntHMap emptyMap; + EdgeIntersections emptyIsects; - const ScalarType eps = (ScalarType)(1e-6); + const ScalarType eps = (ScalarType)(1e-6); - for (ConstFaceIterator it=m.face.begin(); it!=m.face.end(); ++it) - { - if ((*it).IsD()) - { - continue; - } + for (ConstFaceIterator it=m.face.begin(); it!=m.face.end(); ++it) + { + if ((*it).IsD()) + { + continue; + } - unsigned int cc[3]; + unsigned int cc[3]; - cc[0] = ClassType::BoxClipCode(boxOffsets, (*it).V(0)->P()); - cc[1] = ClassType::BoxClipCode(boxOffsets, (*it).V(1)->P()); - cc[2] = ClassType::BoxClipCode(boxOffsets, (*it).V(2)->P()); + cc[0] = ClassType::BoxClipCode(boxOffsets, (*it).V(0)->P()); + cc[1] = ClassType::BoxClipCode(boxOffsets, (*it).V(1)->P()); + cc[2] = ClassType::BoxClipCode(boxOffsets, (*it).V(2)->P()); - if ((cc[0] | cc[1] | cc[2]) == 0) - { - TriangleInfo tnfo; + if ((cc[0] | cc[1] | cc[2]) == 0) + { + TriangleInfo tnfo; VertexClipInfo vnfo; - tnfo.idx = tIdx++; + tnfo.idx = tIdx++; - for (int i=0; i<3; ++i) - { - const unsigned int v = (*it).V(i) - &(*(m.vert.begin())); - std::pair hi = origVertsMap.insert(std::make_pair(v, vIdx)); + for (int i=0; i<3; ++i) + { + const unsigned int v = (*it).V(i) - &(*(m.vert.begin())); + std::pair hi = origVertsMap.insert(std::make_pair(v, vIdx)); - if (hi.second) - { - vnfo.idx = v; - vInfos.push_back(vnfo); - tnfo.v[i] = vIdx++; - } - else - { - tnfo.v[i] = (*(hi.first)).second; - } - } + if (hi.second) + { + vnfo.idx = v; + vInfos.push_back(vnfo); + tnfo.v[i] = vIdx++; + } + else + { + tnfo.v[i] = (*(hi.first)).second; + } + } - tInfos.push_back(tnfo); + tInfos.push_back(tnfo); - continue; - } + continue; + } - if ((cc[0] & cc[1] & cc[2]) != 0) - { - numDeletedTris++; - continue; - } + if ((cc[0] & cc[1] & cc[2]) != 0) + { + numDeletedTris++; + continue; + } - vTriangle[0] = (*it).V(0)->P(); - vTriangle[1] = (*it).V(1)->P(); - vTriangle[2] = (*it).V(2)->P(); - vTriangle[3] = (*it).V(0)->P(); + vTriangle[0] = (*it).V(0)->P(); + vTriangle[1] = (*it).V(1)->P(); + vTriangle[2] = (*it).V(2)->P(); + vTriangle[3] = (*it).V(0)->P(); - unsigned int n, n0, n1; + unsigned int n, n0, n1; - ClipPolygonLine(0, b.min[0], vTriangle, 4, pvP1, n1); - ClipPolygonLine(1, b.max[0], pvP1, n1, pvP0, n0); + ClipPolygonLine(0, b.min[0], vTriangle, 4, pvP1, n1); + ClipPolygonLine(1, b.max[0], pvP1, n1, pvP0, n0); - ClipPolygonLine(2, b.min[1], pvP0, n0, pvP1, n1); - ClipPolygonLine(3, b.max[1], pvP1, n1, pvP0, n0); + ClipPolygonLine(2, b.min[1], pvP0, n0, pvP1, n1); + ClipPolygonLine(3, b.max[1], pvP1, n1, pvP0, n0); - ClipPolygonLine(4, b.min[2], pvP0, n0, pvP1, n1); - ClipPolygonLine(5, b.max[2], pvP1, n1, vClipped, n); + ClipPolygonLine(4, b.min[2], pvP0, n0, pvP1, n1); + ClipPolygonLine(5, b.max[2], pvP1, n1, vClipped, n); - assert(n < 64); + assert(n < 64); - unsigned int firstV, lastV; + unsigned int firstV, lastV; - if (n > 2) - { - if (vClipped[0] == vClipped[n - 1]) - { - n--; - } + if (n > 2) + { + if (vClipped[0] == vClipped[n - 1]) + { + n--; + } - const CoordType vU = vTriangle[1] - vTriangle[0]; - const CoordType vV = vTriangle[2] - vTriangle[0]; + const CoordType vU = vTriangle[1] - vTriangle[0]; + const CoordType vV = vTriangle[2] - vTriangle[0]; - const ScalarType tArea = (vU ^ vV).SquaredNorm(); - if (tArea < eps) - { - continue; - } + const ScalarType tArea = (vU ^ vV).SquaredNorm(); + if (tArea < eps) + { + continue; + } - unsigned int tvidx[3]; - tvidx[0] = (*it).V(0) - &(*(m.vert.begin())); - tvidx[1] = (*it).V(1) - &(*(m.vert.begin())); - tvidx[2] = (*it).V(2) - &(*(m.vert.begin())); + unsigned int tvidx[3]; + tvidx[0] = (*it).V(0) - &(*(m.vert.begin())); + tvidx[1] = (*it).V(1) - &(*(m.vert.begin())); + tvidx[2] = (*it).V(2) - &(*(m.vert.begin())); - unsigned int refT = (unsigned int)(std::distance(m.face.begin(), it)); + unsigned int refT = (unsigned int)(std::distance(m.face.begin(), it)); - numTriangles += n - 2; - - size_t vBegin = vInfos.size(); + numTriangles += n - 2; VertexClipInfo vnfo; - TriangleInfo tnfo; + TriangleInfo tnfo; - unsigned int vmin[3]; - unsigned int vmax[3]; + unsigned int vmin[3]; + unsigned int vmax[3]; - if (tvidx[0] < tvidx[1]) - { - vmin[0] = tvidx[0]; - vmax[0] = tvidx[1]; - } - else - { - vmin[0] = tvidx[1]; - vmax[0] = tvidx[0]; - } + if (tvidx[0] < tvidx[1]) + { + vmin[0] = tvidx[0]; + vmax[0] = tvidx[1]; + } + else + { + vmin[0] = tvidx[1]; + vmax[0] = tvidx[0]; + } - if (tvidx[0] < tvidx[2]) - { - vmin[1] = tvidx[0]; - vmax[1] = tvidx[2]; - } - else - { - vmin[1] = tvidx[2]; - vmax[1] = tvidx[0]; - } + if (tvidx[0] < tvidx[2]) + { + vmin[1] = tvidx[0]; + vmax[1] = tvidx[2]; + } + else + { + vmin[1] = tvidx[2]; + vmax[1] = tvidx[0]; + } - if (tvidx[1] < tvidx[2]) - { - vmin[2] = tvidx[1]; - vmax[2] = tvidx[2]; - } - else - { - vmin[2] = tvidx[2]; - vmax[2] = tvidx[1]; - } + if (tvidx[1] < tvidx[2]) + { + vmin[2] = tvidx[1]; + vmax[2] = tvidx[2]; + } + else + { + vmin[2] = tvidx[2]; + vmax[2] = tvidx[1]; + } - for (unsigned int i=0; i hi = origVertsMap.insert(std::make_pair(tvidx[0], vIdx)); - if (hi.second) - { - vnfo.idx = tvidx[0]; - vInfos.push_back(vnfo); - currVIdx = vIdx++; - } - else - { - currVIdx = (*(hi.first)).second; - } - } - else if (vClipped[i] == vTriangle[1]) - { - std::pair hi = origVertsMap.insert(std::make_pair(tvidx[1], vIdx)); - if (hi.second) - { - vnfo.idx = tvidx[1]; - vInfos.push_back(vnfo); - currVIdx = vIdx++; - } - else - { - currVIdx = (*(hi.first)).second; - } - } - else if (vClipped[i] == vTriangle[2]) - { - std::pair hi = origVertsMap.insert(std::make_pair(tvidx[2], vIdx)); - if (hi.second) - { - vnfo.idx = tvidx[2]; - vInfos.push_back(vnfo); - currVIdx = vIdx++; - } - else - { - currVIdx = (*(hi.first)).second; - } - } - else if (vnfo.fV < eps) - { - std::pair mi = edges.insert(std::make_pair(vmin[1], emptyMap)); - std::pair hi = (*(mi.first)).second.insert(std::make_pair(vmax[1], emptyIsects)); - bool found = false; - for (unsigned int s=0; s<(*(hi.first)).second.n; ++s) - { - if (vClipped[i] == (*(hi.first)).second.isects[s].p) - { - found = true; - vnfo.idx = (unsigned int)(-1); - currVIdx = (*(hi.first)).second.isects[s].idx; - break; - } - } - if (!found) - { - (*(hi.first)).second.isects[(*(hi.first)).second.n].p = vClipped[i]; - (*(hi.first)).second.isects[(*(hi.first)).second.n].idx = vIdx; - (*(hi.first)).second.n++; + if (vClipped[i] == vTriangle[0]) + { + std::pair hi = origVertsMap.insert(std::make_pair(tvidx[0], vIdx)); + if (hi.second) + { + vnfo.idx = tvidx[0]; + vInfos.push_back(vnfo); + currVIdx = vIdx++; + } + else + { + currVIdx = (*(hi.first)).second; + } + } + else if (vClipped[i] == vTriangle[1]) + { + std::pair hi = origVertsMap.insert(std::make_pair(tvidx[1], vIdx)); + if (hi.second) + { + vnfo.idx = tvidx[1]; + vInfos.push_back(vnfo); + currVIdx = vIdx++; + } + else + { + currVIdx = (*(hi.first)).second; + } + } + else if (vClipped[i] == vTriangle[2]) + { + std::pair hi = origVertsMap.insert(std::make_pair(tvidx[2], vIdx)); + if (hi.second) + { + vnfo.idx = tvidx[2]; + vInfos.push_back(vnfo); + currVIdx = vIdx++; + } + else + { + currVIdx = (*(hi.first)).second; + } + } + else if (vnfo.fV < eps) + { + std::pair mi = edges.insert(std::make_pair(vmin[1], emptyMap)); + std::pair hi = (*(mi.first)).second.insert(std::make_pair(vmax[1], emptyIsects)); + bool found = false; + for (unsigned int s=0; s<(*(hi.first)).second.n; ++s) + { + if (vClipped[i] == (*(hi.first)).second.isects[s].p) + { + found = true; + vnfo.idx = (unsigned int)(-1); + currVIdx = (*(hi.first)).second.isects[s].idx; + break; + } + } + if (!found) + { + (*(hi.first)).second.isects[(*(hi.first)).second.n].p = vClipped[i]; + (*(hi.first)).second.isects[(*(hi.first)).second.n].idx = vIdx; + (*(hi.first)).second.n++; - vnfo.idx = (unsigned int)(-1); - numVertices++; - vInfos.push_back(vnfo); - currVIdx = vIdx++; - } - } - else if (vnfo.fU < eps) - { - std::pair mi = edges.insert(std::make_pair(vmin[0], emptyMap)); - std::pair hi = (*(mi.first)).second.insert(std::make_pair(vmax[0], emptyIsects)); - bool found = false; - for (unsigned int s=0; s<(*(hi.first)).second.n; ++s) - { - if (vClipped[i] == (*(hi.first)).second.isects[s].p) - { - found = true; - vnfo.idx = (unsigned int)(-1); - currVIdx = (*(hi.first)).second.isects[s].idx; - break; - } - } - if (!found) - { - (*(hi.first)).second.isects[(*(hi.first)).second.n].p = vClipped[i]; - (*(hi.first)).second.isects[(*(hi.first)).second.n].idx = vIdx; - (*(hi.first)).second.n++; + vnfo.idx = (unsigned int)(-1); + numVertices++; + vInfos.push_back(vnfo); + currVIdx = vIdx++; + } + } + else if (vnfo.fU < eps) + { + std::pair mi = edges.insert(std::make_pair(vmin[0], emptyMap)); + std::pair hi = (*(mi.first)).second.insert(std::make_pair(vmax[0], emptyIsects)); + bool found = false; + for (unsigned int s=0; s<(*(hi.first)).second.n; ++s) + { + if (vClipped[i] == (*(hi.first)).second.isects[s].p) + { + found = true; + vnfo.idx = (unsigned int)(-1); + currVIdx = (*(hi.first)).second.isects[s].idx; + break; + } + } + if (!found) + { + (*(hi.first)).second.isects[(*(hi.first)).second.n].p = vClipped[i]; + (*(hi.first)).second.isects[(*(hi.first)).second.n].idx = vIdx; + (*(hi.first)).second.n++; - vnfo.idx = (unsigned int)(-1); - numVertices++; - vInfos.push_back(vnfo); - currVIdx = vIdx++; - } - } - else if ((vnfo.fU + vnfo.fV) >= ((ScalarType)(1.0 - 1e-5))) - { - std::pair mi = edges.insert(std::make_pair(vmin[2], emptyMap)); - std::pair hi = (*(mi.first)).second.insert(std::make_pair(vmax[2], emptyIsects)); - bool found = false; - for (unsigned int s=0; s<(*(hi.first)).second.n; ++s) - { - if (vClipped[i] == (*(hi.first)).second.isects[s].p) - { - found = true; - vnfo.idx = (unsigned int)(-1); - currVIdx = (*(hi.first)).second.isects[s].idx; - break; - } - } - if (!found) - { - (*(hi.first)).second.isects[(*(hi.first)).second.n].p = vClipped[i]; - (*(hi.first)).second.isects[(*(hi.first)).second.n].idx = vIdx; - (*(hi.first)).second.n++; + vnfo.idx = (unsigned int)(-1); + numVertices++; + vInfos.push_back(vnfo); + currVIdx = vIdx++; + } + } + else if ((vnfo.fU + vnfo.fV) >= ((ScalarType)(1.0 - 1e-5))) + { + std::pair mi = edges.insert(std::make_pair(vmin[2], emptyMap)); + std::pair hi = (*(mi.first)).second.insert(std::make_pair(vmax[2], emptyIsects)); + bool found = false; + for (unsigned int s=0; s<(*(hi.first)).second.n; ++s) + { + if (vClipped[i] == (*(hi.first)).second.isects[s].p) + { + found = true; + vnfo.idx = (unsigned int)(-1); + currVIdx = (*(hi.first)).second.isects[s].idx; + break; + } + } + if (!found) + { + (*(hi.first)).second.isects[(*(hi.first)).second.n].p = vClipped[i]; + (*(hi.first)).second.isects[(*(hi.first)).second.n].idx = vIdx; + (*(hi.first)).second.n++; - vnfo.idx = (unsigned int)(-1); - numVertices++; - vInfos.push_back(vnfo); - currVIdx = vIdx++; - } - } - else - { - vnfo.idx = (unsigned int)(-1); - numVertices++; - vInfos.push_back(vnfo); - currVIdx = vIdx++; - } + vnfo.idx = (unsigned int)(-1); + numVertices++; + vInfos.push_back(vnfo); + currVIdx = vIdx++; + } + } + else + { + vnfo.idx = (unsigned int)(-1); + numVertices++; + vInfos.push_back(vnfo); + currVIdx = vIdx++; + } - if (i == 0) - { - firstV = currVIdx; - } + if (i == 0) + { + firstV = currVIdx; + } - if (i > 1) - { - tnfo.idx = tIdx++; - tnfo.v[0] = firstV; - tnfo.v[1] = lastV; - tnfo.v[2] = currVIdx; + if (i > 1) + { + tnfo.idx = tIdx++; + tnfo.v[0] = firstV; + tnfo.v[1] = lastV; + tnfo.v[2] = currVIdx; - tInfos.push_back(tnfo); - } + tInfos.push_back(tnfo); + } - lastV = currVIdx; - } - } - } + lastV = currVIdx; + } + } + } - if (tInfos.empty()) - { - return; - } + if (tInfos.empty()) + { + return; + } - const unsigned int vSize = (unsigned int)(m.vn); - const unsigned int tSize = (unsigned int)(m.fn); + typedef Allocator TriMeshAllocatorType; - typedef Allocator TriMeshAllocatorType; + TriMeshAllocatorType::AddVertices(r, (int)(vInfos.size())); + TriMeshAllocatorType::AddFaces(r, (int)(tInfos.size())); - TriMeshAllocatorType::AddVertices(r, (int)(vInfos.size())); - TriMeshAllocatorType::AddFaces(r, (int)(tInfos.size())); + for (size_t i=0; i value + eps; - break; - case 2: - flag = p_in[1] + eps < value; - break; - case 3: - flag = p_in[1] > value + eps; - break; - case 4: - flag = p_in[2] + eps < value; - break; - case 5: - flag = p_in[2] > value + eps; - break; - default: - break; - } + switch(mode) + { + case 0: + flag = p_in[0] + eps < value; + break; + case 1: + flag = p_in[0] > value + eps; + break; + case 2: + flag = p_in[1] + eps < value; + break; + case 3: + flag = p_in[1] > value + eps; + break; + case 4: + flag = p_in[2] + eps < value; + break; + case 5: + flag = p_in[2] > value + eps; + break; + default: + break; + } - return (flag); - } + return (flag); + } - static inline void CrossPoint(int mode, const ScalarType & value, const CoordType & SP, const CoordType & PP, CoordType & p_out) - { - switch(mode) - { - case 0: - case 1: - p_out[0] = value; - if ((PP[0] - SP[0]) == ((ScalarType)(0))) - { - p_out[1] = PP[1]; - p_out[2] = PP[2]; - } - else - { - p_out[1] = SP[1] + (value - SP[0]) * (PP[1] - SP[1]) / (PP[0] - SP[0]); - p_out[2] = SP[2] + (value - SP[0]) * (PP[2] - SP[2]) / (PP[0] - SP[0]); - } - break; - case 2: - case 3: - p_out[1] = value; - if ((PP[1] - SP[1]) == ((ScalarType)(0))) - { - p_out[0] = PP[0]; - p_out[2] = PP[2]; - } - else - { - p_out[0] = SP[0] + (value - SP[1]) * (PP[0] - SP[0]) / (PP[1] - SP[1]); - p_out[2] = SP[2] + (value - SP[1]) * (PP[2] - SP[2]) / (PP[1] - SP[1]); - } - break; - case 4: - case 5: - p_out[2] = value; - if ((PP[2] - SP[2]) == ((ScalarType)(0))) - { - p_out[0] = PP[0]; - p_out[1] = PP[1]; - } - else - { - p_out[0] = SP[0] + (value - SP[2]) * (PP[0] - SP[0]) / (PP[2] - SP[2]); - p_out[1] = SP[1] + (value - SP[2]) * (PP[1] - SP[1]) / (PP[2] - SP[2]); - } - break; - default: - break; - } - } + static inline void CrossPoint(int mode, const ScalarType & value, const CoordType & SP, const CoordType & PP, CoordType & p_out) + { + switch(mode) + { + case 0: + case 1: + p_out[0] = value; + if ((PP[0] - SP[0]) == ((ScalarType)(0))) + { + p_out[1] = PP[1]; + p_out[2] = PP[2]; + } + else + { + p_out[1] = SP[1] + (value - SP[0]) * (PP[1] - SP[1]) / (PP[0] - SP[0]); + p_out[2] = SP[2] + (value - SP[0]) * (PP[2] - SP[2]) / (PP[0] - SP[0]); + } + break; + case 2: + case 3: + p_out[1] = value; + if ((PP[1] - SP[1]) == ((ScalarType)(0))) + { + p_out[0] = PP[0]; + p_out[2] = PP[2]; + } + else + { + p_out[0] = SP[0] + (value - SP[1]) * (PP[0] - SP[0]) / (PP[1] - SP[1]); + p_out[2] = SP[2] + (value - SP[1]) * (PP[2] - SP[2]) / (PP[1] - SP[1]); + } + break; + case 4: + case 5: + p_out[2] = value; + if ((PP[2] - SP[2]) == ((ScalarType)(0))) + { + p_out[0] = PP[0]; + p_out[1] = PP[1]; + } + else + { + p_out[0] = SP[0] + (value - SP[2]) * (PP[0] - SP[0]) / (PP[2] - SP[2]); + p_out[1] = SP[1] + (value - SP[2]) * (PP[1] - SP[1]) / (PP[2] - SP[2]); + } + break; + default: + break; + } + } - static inline void ClipPolygonLine(int mode, const ScalarType & value, CoordType * P_in, unsigned int n_in, CoordType * P_out, unsigned int & n_out) - { - unsigned int ps; - CoordType * SP; - CoordType * PP; + static inline void ClipPolygonLine(int mode, const ScalarType & value, CoordType * P_in, unsigned int n_in, CoordType * P_out, unsigned int & n_out) + { + unsigned int ps; + CoordType * SP; + CoordType * PP; - n_out = 0; - SP = &P_in[n_in-1]; + n_out = 0; + SP = &P_in[n_in-1]; - if (ClassType::InRegion(mode, value, *SP)) - { - ps = 0; - } - else - { - ps = 2; - } + if (ClassType::InRegion(mode, value, *SP)) + { + ps = 0; + } + else + { + ps = 2; + } - for(unsigned int i=0; i> 1) | ((ClassType::InRegion(mode, value, *PP)) ? (0) : (2)); + for(unsigned int i=0; i> 1) | ((ClassType::InRegion(mode, value, *PP)) ? (0) : (2)); - switch(ps) - { - case 0: - break; - case 1: - ClassType::CrossPoint(mode, value, *SP, *PP, P_out[n_out]); - n_out++; - break; - case 2: - ClassType::CrossPoint(mode, value, *SP, *PP, P_out[n_out]); - n_out++; - P_out[n_out] = *PP; - n_out++; - break; - case 3: - P_out[n_out] = *PP; - n_out++; - break; - default: - break; - } + switch(ps) + { + case 0: + break; + case 1: + ClassType::CrossPoint(mode, value, *SP, *PP, P_out[n_out]); + n_out++; + break; + case 2: + ClassType::CrossPoint(mode, value, *SP, *PP, P_out[n_out]); + n_out++; + P_out[n_out] = *PP; + n_out++; + break; + case 3: + P_out[n_out] = *PP; + n_out++; + break; + default: + break; + } - SP = PP; - } - } + SP = PP; + } + } };