7 #include "fwMath/MeshFunctions.hpp" 8 #include "fwMath/VectorFunctions.hpp" 10 #include <boost/unordered_map.hpp> 21 fwVec3d _vert1, fwVec3d _vert2,
22 double &_t,
double &_u,
double &_v)
24 const double Epsilon = 0.000001;
26 fwVec3d edge1, edge2, tvec, pvec, qvec;
29 edge1 = _vert1 - _vert0;
30 edge2 = _vert2 - _vert0;
33 pvec = ::fwMath::cross(_dir, edge2);
36 const double Det = ::fwMath::dot(edge1, pvec);
38 if (Det > -Epsilon && Det < Epsilon)
42 const double Inv_det = 1.0 / Det;
45 tvec = _orig - _vert0;
48 _u = Inv_det * ::fwMath::dot(tvec, pvec);
49 if (_u < 0.0 || _u > 1.0)
55 qvec = ::fwMath::cross(tvec, edge1);
58 _v = Inv_det * ::fwMath::dot(_dir, qvec);
59 if (_v < 0.0 || _u + _v > 1.0)
65 _t = Inv_det * ::fwMath::dot(edge2, qvec);
71 bool IsInclosedVolume(
const fwVertexPosition &_vertex,
const fwVertexIndex &_vertexIndex,
const fwVec3d &_p)
73 const unsigned int X = 0, Y = 1, Z = 2;
74 const size_t ElementNbr = _vertexIndex.size();
75 if ( ElementNbr == 0 )
81 unsigned int intersectionNbr = 0;
82 for (
size_t i = 0; i < ElementNbr; ++i )
86 {_vertex[ _vertexIndex[i][0] ][0], _vertex[ _vertexIndex[i][0] ][1], _vertex[ _vertexIndex[i][0] ][2]};
88 {_vertex[ _vertexIndex[i][1] ][0], _vertex[ _vertexIndex[i][1] ][1], _vertex[ _vertexIndex[i][1] ][2]};
90 {_vertex[ _vertexIndex[i][2] ][0], _vertex[ _vertexIndex[i][2] ][1], _vertex[ _vertexIndex[i][2] ][2]};
94 "Trg : " << i <<
" with Z = [" << P1[Z] <<
"][" << P2[Z] <<
"][" << P3[Z] <<
"] compare with " <<
97 if ( !(P1[Z] > _p[Z] && P2[Z] > _p[Z] && P3[Z] > _p[Z] ) )
103 for (
unsigned int axe = X; axe <= Y && !stop; ++axe )
105 const double Delta1 = P1[axe] - _p[axe];
106 const double Delta2 = P2[axe] - _p[axe];
107 const double Delta3 = P3[axe] - _p[axe];
109 OSLM_TRACE(
"d1 : " << Delta1 <<
"d2 : " << Delta2 <<
"d3 : " << Delta3 );
111 if ( Delta1 >= 0.f && Delta2 >= 0.f && Delta3 >= 0.f )
115 if ( Delta1 < 0.f && Delta2 < 0.f && Delta3 < 0.f )
122 OSLM_TRACE(
"The face(" << i <<
") is interesting to find a point in volume");
124 fwVec3d orig = {_p[0], _p[1], _p[2]};
126 fwVec3d dir = { 0.f, 0.f, 1.f};
127 fwVec3d vert0 = { P1[0], P1[1], P1[2]};
128 fwVec3d vert1 = { P2[0], P2[1], P2[2]};
129 fwVec3d vert2 = { P3[0], P3[1], P3[2]};
136 OSLM_TRACE(
" t = " << t <<
" u = " << u <<
" v = " << v);
143 OSLM_TRACE(
"Nb intersection : " << intersectionNbr);
144 return ( intersectionNbr%2 == 1 );
151 typedef std::pair< int, int > Edge;
152 typedef ::boost::unordered_map< Edge, int > EdgeHistogram;
153 EdgeHistogram edgesHistogram;
154 bool isBorderless =
true;
156 for(
const fwVertexIndex::value_type &vertex : _vertexIndex)
158 OSLM_ASSERT(
"Invalid vertex size: "<< vertex.size(), vertex.size() > 2 );
159 ++edgesHistogram[std::make_pair(std::min(vertex[0],vertex[1]), std::max(vertex[0],vertex[1]) )];
160 ++edgesHistogram[std::make_pair(std::min(vertex[0],vertex[2]), std::max(vertex[0],vertex[2]) )];
161 ++edgesHistogram[std::make_pair(std::min(vertex[2],vertex[1]), std::max(vertex[2],vertex[1]) )];
164 for(
const EdgeHistogram::value_type &histo : edgesHistogram)
168 isBorderless =
false;
179 void findBorderEdges(
const fwVertexIndex &_vertexIndex,
180 std::vector< std::vector< std::pair< int, int > > > &contours)
182 typedef std::pair< int, int > Edge;
183 typedef std::vector< Edge > Contour;
184 typedef std::vector< Contour> Contours;
186 std::map< Edge, int > edgesHistogram;
187 for ( fwVertexIndex::value_type vertex : _vertexIndex)
189 assert(vertex.size() > 2 );
193 edgesHistogram[std::make_pair(std::min(i1,i2), std::max(i1,i2) )]++;
194 edgesHistogram[std::make_pair(std::min(i1,i3), std::max(i1,i3) )]++;
195 edgesHistogram[std::make_pair(std::min(i3,i2), std::max(i3,i2) )]++;
198 for (
const std::map< Edge, int >::value_type& elt1 : edgesHistogram )
203 contour.reserve(1000);
204 std::list< Edge > fifo;
205 Edge orphan = elt1.first;
207 fifo.push_back(orphan);
208 while( !fifo.empty() )
210 Edge current = fifo.front();
211 contour.push_back( current );
213 edgesHistogram[current] = 2;
216 for (
const std::map< Edge, int >::value_type& elt2 : edgesHistogram )
218 Edge candidate = elt2.first;
219 if ( elt2.second < 2 )
221 if ( candidate.first == current.first || candidate.second == current.second ||
222 candidate.first == current.second || candidate.second == current.first
225 edgesHistogram[candidate] = 2;
226 fifo.push_back( candidate );
232 contours.push_back( contour );
239 bool closeSurface( fwVertexPosition &_vertex, fwVertexIndex &_vertexIndex )
241 typedef std::pair< int, int > Edge;
242 typedef std::vector< Edge > Contour;
243 typedef std::vector< Contour> Contours;
246 findBorderEdges( _vertexIndex, contours);
247 bool closurePerformed = !contours.empty();
249 for(
const Contours::value_type& contour : contours )
251 size_t newVertexIndex = _vertex.size();
253 std::vector< float > massCenter(3,0);
255 for (
const Contour::value_type& edge : contour )
257 for (
int i = 0; i<3; ++i )
259 massCenter[i] += _vertex[edge.first][i];
260 massCenter[i] += _vertex[edge.second][i];
263 std::vector< int > triangleIndex(3);
264 triangleIndex[0] = edge.first;
265 triangleIndex[1] = edge.second;
266 triangleIndex[2] = newVertexIndex;
267 _vertexIndex.push_back( triangleIndex );
269 for (
int i = 0; i<3; ++i )
271 massCenter[i] /= contour.size()*2;
273 _vertex.push_back( massCenter );
275 return closurePerformed;
282 fwVertexPosition newVertex;
283 newVertex.reserve( _vertex.size() );
285 std::set< int > indexPointToKeep;
287 for(
const fwVertexIndex::value_type& vertex : _vertexIndex )
289 indexPointToKeep.insert( vertex[0] );
290 indexPointToKeep.insert( vertex[1] );
291 indexPointToKeep.insert( vertex[2] );
294 bool orphanFound = indexPointToKeep.size() != _vertex.size();
300 std::map< int, int > translate;
301 std::set< int >::iterator idxIter;
302 for (
int indexPt : indexPointToKeep )
304 translate[ indexPt ] = idx++;
305 newVertex.push_back( _vertex[ indexPt ] );
308 for (fwVertexIndex::value_type& vertex : _vertexIndex )
310 vertex[0] = translate[ vertex[0] ];
311 vertex[1] = translate[ vertex[1] ];
312 vertex[2] = translate[ vertex[2] ];
314 _vertex.swap(newVertex);
FWMATH_API bool removeOrphanVertices(fwVertexPosition &_vertex, fwVertexIndex &_vertexIndex)
#define OSLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
#define OSLM_TRACE(message)
FWMATH_API bool closeSurface(fwVertexPosition &_vertex, fwVertexIndex &_vertexIndex)
Closes the surface if necessary.
FWMATH_API bool intersect_triangle(fwVec3d _orig, fwVec3d _dir, fwVec3d _vert0, fwVec3d _vert1, fwVec3d _vert2, double &_t, double &_u, double &_v)
Compute the intersection between triangle(define by threes vertex vert1, vert2, vert3) and the Oz par...
The namespace fwMath contains classes which provide the implementation of several mathematic function...
FWMATH_API bool isBorderlessSurface(const fwVertexIndex &_vertexIndex)
test whatever a vertex is duplicated or not