mirror of https://github.com/CGAL/cgal
Merge pull request #2057 from janetournois/PMP-fix_is_outward_oriented-GF
PMP : fix `PMP::is_outward_oriented()`
This commit is contained in:
commit
2ad18ad5d7
|
|
@ -96,6 +96,13 @@ namespace CartesianKernelFunctors {
|
|||
r.x(), r.y(), r.z(),
|
||||
s.x(), s.y(), s.z());
|
||||
}
|
||||
|
||||
result_type
|
||||
operator()(const Point_3& p, const Point_3& q,
|
||||
const Point_3& r, const Vector_3& n) const
|
||||
{
|
||||
return enum_cast<Angle>(orientation(p,q,r,r+n));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename K>
|
||||
|
|
|
|||
|
|
@ -112,6 +112,13 @@ namespace HomogeneousKernelFunctors {
|
|||
const Point_3& r, const Point_3& s) const
|
||||
{ return enum_cast<Angle>(CGAL_NTS sign(c(q,p) * c(s,r))); }
|
||||
// FIXME: scalar product
|
||||
|
||||
result_type
|
||||
operator()(const Point_3& p, const Point_3& q,
|
||||
const Point_3& r, const Vector_3& n) const
|
||||
{
|
||||
return enum_cast<Angle>(orientation(p,q,r,r+n));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -205,11 +205,20 @@ and <code>src/</code> directories).
|
|||
|
||||
<h3>2D and 3D Linear Geometry Kernel</h3>
|
||||
<ul>
|
||||
<li><b>Breaking change</b>: The function <code>compare_slopes()</code> was renamed <code>compare_slope</code>.
|
||||
</li>
|
||||
<li>Added a 2D and 3D weighted point class and predicates and constructions.
|
||||
</li>
|
||||
<li>
|
||||
Add functions <code>l_infinity_distance()</code> for 2D and 3D.
|
||||
</li>
|
||||
<li>Add a new functor in CGAL Kernel concept to compare the slope of two 3D segments.
|
||||
All models of the Kernel concept now provide the functor <code>Compare_slope_3</code>,
|
||||
and the free function <code>compare_slope()</code> is available.
|
||||
</li>
|
||||
<li>Add an operator in CGAL Kernel concept <code>Angle_3</code> to qualify the angle
|
||||
between the normal of the triangle given by three points, and a vector.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>3D Convex Hull</h3>
|
||||
|
|
|
|||
|
|
@ -38,7 +38,15 @@ const CGAL::Point_2<Kernel>& r,
|
|||
const CGAL::Point_2<Kernel>& s);
|
||||
|
||||
/*!
|
||||
returns \ref CGAL::OBTUSE, \ref CGAL::RIGHT or \ref CGAL::ACUTE depending
|
||||
on the angle formed by the two vectors `u` and `v`.
|
||||
*/
|
||||
template <typename Kernel>
|
||||
Angle angle(const CGAL::Vector_3<Kernel>& u,
|
||||
const CGAL::Vector_3<Kernel>& v);
|
||||
|
||||
|
||||
/*!
|
||||
returns `CGAL::OBTUSE`, `CGAL::RIGHT` or `CGAL::ACUTE` depending
|
||||
on the angle formed by the three points `p`, `q`, `r` (`q` being the vertex of
|
||||
the angle).
|
||||
|
|
@ -48,6 +56,29 @@ Angle angle(const CGAL::Point_3<Kernel>& p,
|
|||
const CGAL::Point_3<Kernel>& q,
|
||||
const CGAL::Point_3<Kernel>& r);
|
||||
|
||||
/*!
|
||||
returns \ref CGAL::OBTUSE, \ref CGAL::RIGHT or \ref CGAL::ACUTE depending
|
||||
on the angle formed by the two vectors `pq`, `rs`. The returned value is
|
||||
the same as `angle(q - p, s - r)`.
|
||||
*/
|
||||
template<typename Kernel >
|
||||
Angle angle(const CGAL::Point_3<Kernel>&p,
|
||||
const CGAL::Point_3<Kernel>&q,
|
||||
const CGAL::Point_3<Kernel>&r,
|
||||
const CGAL::Point_3<Kernel>&s);
|
||||
|
||||
/*!
|
||||
returns \ref CGAL::OBTUSE, \ref CGAL::RIGHT or \ref CGAL::ACUTE depending
|
||||
on the angle formed by the normal of the triangle `pqr` and the vector `v`.
|
||||
*/
|
||||
|
||||
template<typename Kernel >
|
||||
Angle angle(const CGAL::Point_3<Kernel>&p,
|
||||
const CGAL::Point_3<Kernel>&q,
|
||||
const CGAL::Point_3<Kernel>&r,
|
||||
const CGAL::Vector_3<Kernel>&v);
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
returns an approximation of the signed dihedral angle in the tetrahedron `pqrs` of edge `pq`.
|
||||
|
|
@ -61,6 +92,7 @@ Kernel::FT approximate_dihedral_angle(const CGAL::Point_3<Kernel>& p,
|
|||
const CGAL::Point_3<Kernel>& r,
|
||||
const CGAL::Point_3<Kernel>& s);
|
||||
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
|
|
@ -793,16 +825,28 @@ const CGAL::Point_3<Kernel>& t);
|
|||
compares the slopes of the lines `l1` and `l2`
|
||||
*/
|
||||
template <typename Kernel>
|
||||
Comparison_result compare_slopes(const CGAL::Line_2<Kernel> &l1,
|
||||
Comparison_result compare_slope(const CGAL::Line_2<Kernel> &l1,
|
||||
const CGAL::Line_2<Kernel> &l2);
|
||||
|
||||
/*!
|
||||
compares the slopes of the segments `s1` and `s2`
|
||||
compares the slopes of the segments `s1` and `s2`,
|
||||
where the slope is the variation of the `y`-coordinate
|
||||
from the left to the right endpoint of the segments.
|
||||
*/
|
||||
template <typename Kernel>
|
||||
Comparison_result compare_slopes(const CGAL::Segment_2<Kernel> &s1,
|
||||
Comparison_result compare_slope(const CGAL::Segment_2<Kernel> &s1,
|
||||
const CGAL::Segment_2<Kernel> &s2);
|
||||
|
||||
/*!
|
||||
compares the slopes of the segments `(p,q)` and `(r,s)`,
|
||||
where the slope is the variation of the `z`-coordinate from the first
|
||||
to the second point of the segment divided by the length of the segment.
|
||||
*/
|
||||
template <typename Kernel>
|
||||
Comparison_result compare_slope(const CGAL::Point_3<Kernel> &p,
|
||||
const CGAL::Point_3<Kernel> &q,
|
||||
const CGAL::Point_3<Kernel> &r,
|
||||
const CGAL::Point_3<Kernel> &s);
|
||||
/// @}
|
||||
|
||||
/// \defgroup compare_squared_distance_grp CGAL::compare_squared_distance()
|
||||
|
|
|
|||
|
|
@ -62,20 +62,20 @@ public:
|
|||
/// @{
|
||||
|
||||
/*!
|
||||
returns \ref CGAL::OBTUSE, \ref CGAL::RIGHT or \ref CGAL::ACUTE depending
|
||||
on the angle formed by the two vectors `u` and `v`.
|
||||
*/
|
||||
Angle operator()(const Kernel::Vector_3&u,
|
||||
const Kernel::Vector_3&v);
|
||||
returns \ref CGAL::OBTUSE, \ref CGAL::RIGHT or \ref CGAL::ACUTE depending
|
||||
on the angle formed by the two vectors `u` and `v`.
|
||||
*/
|
||||
Angle operator()(const Kernel::Vector_3&u,
|
||||
const Kernel::Vector_3&v);
|
||||
|
||||
/*!
|
||||
returns \ref CGAL::OBTUSE, \ref CGAL::RIGHT or \ref CGAL::ACUTE depending
|
||||
on the angle formed by the three points `p`, `q`, `r` (`q` being the vertex of
|
||||
returns \ref CGAL::OBTUSE, \ref CGAL::RIGHT or \ref CGAL::ACUTE depending
|
||||
on the angle formed by the three points `p`, `q`, `r` (`q` being the vertex of
|
||||
the angle). The returned value is the same as `operator()(p - q, r - q)`.
|
||||
*/
|
||||
Angle operator()(const Kernel::Point_3&p,
|
||||
const Kernel::Point_3&q,
|
||||
const Kernel::Point_3&r);
|
||||
*/
|
||||
Angle operator()(const Kernel::Point_3&p,
|
||||
const Kernel::Point_3&q,
|
||||
const Kernel::Point_3&r);
|
||||
|
||||
/*!
|
||||
returns \ref CGAL::OBTUSE, \ref CGAL::RIGHT or \ref CGAL::ACUTE depending
|
||||
|
|
@ -85,7 +85,16 @@ public:
|
|||
Angle operator()(const Kernel::Point_3&p,
|
||||
const Kernel::Point_3&q,
|
||||
const Kernel::Point_3&r,
|
||||
const Kernel::Point_3&s);
|
||||
const Kernel::Point_3&s);
|
||||
|
||||
/*!
|
||||
returns \ref CGAL::OBTUSE, \ref CGAL::RIGHT or \ref CGAL::ACUTE depending
|
||||
on the angle formed by the normal of the triangle `pqr` and the vector `v`.
|
||||
*/
|
||||
Angle operator()(const Kernel::Point_3&p,
|
||||
const Kernel::Point_3&q,
|
||||
const Kernel::Point_3&r,
|
||||
const Kernel::Vector_3&v);
|
||||
/// @}
|
||||
|
||||
}; /* end Kernel::Angle_3 */
|
||||
|
|
@ -991,7 +1000,9 @@ public:
|
|||
const Kernel::Line_2& l2);
|
||||
|
||||
/*!
|
||||
compares the slopes of the segments `s1` and `s2`
|
||||
compares the slopes of the segments `s1` and `s2`,
|
||||
where the slope is the variation of the `y`-coordinate
|
||||
from the left to the right endpoint of the segments.
|
||||
*/
|
||||
Comparison_result operator()(const Kernel::Segment_2& s1,
|
||||
const Kernel::Segment_2& s2);
|
||||
|
|
@ -1000,6 +1011,42 @@ public:
|
|||
|
||||
}; /* end Kernel::CompareSlope_2 */
|
||||
|
||||
|
||||
/*!
|
||||
\ingroup PkgKernel23ConceptsFunctionObjects
|
||||
\cgalConcept
|
||||
|
||||
\cgalRefines `AdaptableFunctor` (with two arguments)
|
||||
|
||||
\sa `compare_slopes_grp`
|
||||
|
||||
*/
|
||||
class CompareSlope_3 {
|
||||
public:
|
||||
|
||||
/// \name Operations
|
||||
/// A model of this concept must provide:
|
||||
/// @{
|
||||
|
||||
|
||||
/*!
|
||||
compares the slopes of the segments `(p,q)` and `(r,s)`,
|
||||
where the slope is the variation of the `z`-coordinate
|
||||
from the first to the second point of the segment divided
|
||||
by the length of the segment.
|
||||
*/
|
||||
Comparison_result operator()(const Kernel::Point_3& p,
|
||||
const Kernel::Point_3& q,
|
||||
const Kernel::Point_3& r,
|
||||
const Kernel::Point_3& s);
|
||||
|
||||
|
||||
/// @}
|
||||
|
||||
}; /* end Kernel::CompareSlope_3 */
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\ingroup PkgKernel23ConceptsFunctionObjects
|
||||
\cgalConcept
|
||||
|
|
|
|||
|
|
@ -1433,6 +1433,11 @@ public:
|
|||
*/
|
||||
typedef unspecified_type Compare_xyz_3;
|
||||
|
||||
/*!
|
||||
a model of `Kernel::CompareSlope_3`
|
||||
*/
|
||||
typedef unspecified_type Compare_slope_3;
|
||||
|
||||
/*!
|
||||
a model of `Kernel::CompareSquaredDistance_3`
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -276,6 +276,7 @@
|
|||
- `Kernel::CompareDistance_2`
|
||||
- `Kernel::CompareDistance_3`
|
||||
- `Kernel::CompareSlope_2`
|
||||
- `Kernel::CompareSlope_3`
|
||||
- `Kernel::ComparePowerDistance_2`
|
||||
- `Kernel::ComparePowerDistance_3`
|
||||
- `Kernel::CompareSquaredDistance_2`
|
||||
|
|
|
|||
|
|
@ -752,6 +752,36 @@ namespace CommonKernelFunctors {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename K>
|
||||
class Compare_slope_3
|
||||
{
|
||||
typedef typename K::FT FT;
|
||||
typedef typename K::Point_3 Point_3;
|
||||
public:
|
||||
typedef typename K::Comparison_result result_type;
|
||||
|
||||
result_type operator()(const Point_3& p, const Point_3& q, const Point_3& r, const Point_3& s) const
|
||||
{
|
||||
Comparison_result sign_pq = compare(q.z(),p.z());
|
||||
Comparison_result sign_rs = compare(s.z(),r.z());
|
||||
|
||||
if(sign_pq != sign_rs){
|
||||
return compare(static_cast<int>(sign_pq), static_cast<int>(sign_rs));
|
||||
}
|
||||
|
||||
if((sign_pq == EQUAL) && (sign_rs == EQUAL)){
|
||||
return EQUAL;
|
||||
}
|
||||
|
||||
CGAL_assertion( (sign_pq == sign_rs) && (sign_pq != EQUAL) );
|
||||
|
||||
Comparison_result res = CGAL::compare(square(p.z() - q.z()) * (square(r.x()-s.x())+square(r.y()-s.y())),
|
||||
square(r.z() - s.z()) * (square(p.x()-q.x())+square(p.y()-q.y())));
|
||||
return (sign_pq == SMALLER) ? opposite(res) : res;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename K>
|
||||
class Compare_squared_distance_2
|
||||
{
|
||||
|
|
|
|||
|
|
@ -342,18 +342,41 @@ compare_lexicographically_xy(const Point_2<K> &p,
|
|||
template < class K >
|
||||
inline
|
||||
typename K::Comparison_result
|
||||
compare_slopes(const Line_2<K> &l1, const Line_2<K> &l2)
|
||||
compare_slope(const Line_2<K> &l1, const Line_2<K> &l2)
|
||||
{
|
||||
return internal::compare_slopes(l1, l2, K());
|
||||
return internal::compare_slope(l1, l2, K());
|
||||
}
|
||||
|
||||
template < class K >
|
||||
inline
|
||||
typename K::Comparison_result
|
||||
compare_slope(const Segment_2<K> &s1, const Segment_2<K> &s2)
|
||||
{
|
||||
return internal::compare_slope(s1, s2, K());
|
||||
}
|
||||
|
||||
|
||||
#ifndef CGAL_NO_DEPRECATED_CODE
|
||||
// kept for backward compatibility
|
||||
template < class K >
|
||||
CGAL_DEPRECATED_MSG("This function is deprecated. CGAL::compare_slope() should be used instead")
|
||||
inline
|
||||
typename K::Comparison_result
|
||||
compare_slopes(const Line_2<K> &l1, const Line_2<K> &l2)
|
||||
{
|
||||
return internal::compare_slope(l1, l2, K());
|
||||
}
|
||||
|
||||
// kept for backward compatibility
|
||||
template < class K >
|
||||
CGAL_DEPRECATED_MSG("This function is deprecated. CGAL::compare_slope() should be used instead")
|
||||
inline
|
||||
typename K::Comparison_result
|
||||
compare_slopes(const Segment_2<K> &s1, const Segment_2<K> &s2)
|
||||
{
|
||||
return internal::compare_slopes(s1, s2, K());
|
||||
return internal::compare_slope(s1, s2, K());
|
||||
}
|
||||
#endif
|
||||
|
||||
template < class K >
|
||||
inline
|
||||
|
|
|
|||
|
|
@ -59,6 +59,15 @@ angle(const Point_3<K> &p, const Point_3<K> &q,
|
|||
return internal::angle(p, q, r, s, K());
|
||||
}
|
||||
|
||||
template <typename K>
|
||||
inline
|
||||
Angle
|
||||
angle(const Point_3<K> &p, const Point_3<K> &q,
|
||||
const Point_3<K> &r, const Vector_3<K> &v)
|
||||
{
|
||||
return internal::angle(p, q, r, v, K());
|
||||
}
|
||||
|
||||
template < class K >
|
||||
inline
|
||||
typename K::FT
|
||||
|
|
@ -354,6 +363,17 @@ compare_power_distance(const Point_3<K> &r,
|
|||
return internal::compare_power_distance(r, p, q, K());
|
||||
}
|
||||
|
||||
template < class K >
|
||||
inline
|
||||
typename K::Comparison_result
|
||||
compare_slope(const Point_3<K> &p,
|
||||
const Point_3<K> &q,
|
||||
const Point_3<K> &r,
|
||||
const Point_3<K> &s)
|
||||
{
|
||||
return internal::compare_slope(p, q, r, s, K());
|
||||
}
|
||||
|
||||
template < class K >
|
||||
inline
|
||||
typename K::Comparison_result
|
||||
|
|
|
|||
|
|
@ -370,8 +370,8 @@ compare_signed_distance_to_line(const typename K::Line_2& l,
|
|||
template < class K >
|
||||
inline
|
||||
typename K::Comparison_result
|
||||
compare_slopes(const typename K::Line_2 &l1,
|
||||
const typename K::Line_2 &l2, const K& k)
|
||||
compare_slope(const typename K::Line_2 &l1,
|
||||
const typename K::Line_2 &l2, const K& k)
|
||||
{
|
||||
return k.compare_slope_2_object()(l1, l2);
|
||||
}
|
||||
|
|
@ -379,8 +379,8 @@ compare_slopes(const typename K::Line_2 &l1,
|
|||
template < class K >
|
||||
inline
|
||||
typename K::Comparison_result
|
||||
compare_slopes(const typename K::Segment_2 &s1,
|
||||
const typename K::Segment_2 &s2, const K& k)
|
||||
compare_slope(const typename K::Segment_2 &s1,
|
||||
const typename K::Segment_2 &s2, const K& k)
|
||||
{
|
||||
return k.compare_slope_2_object()(s1, s2);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,6 +70,18 @@ angle(const typename K::Point_3 &p,
|
|||
return k.angle_3_object()(p, q, r, s);
|
||||
}
|
||||
|
||||
template <typename K>
|
||||
inline
|
||||
typename K::Angle
|
||||
angle(const typename K::Point_3 &p,
|
||||
const typename K::Point_3 &q,
|
||||
const typename K::Point_3 &r,
|
||||
const typename K::Vector_3 &v,
|
||||
const K &k)
|
||||
{
|
||||
return k.angle_3_object()(p, q, r, v);
|
||||
}
|
||||
|
||||
template < class K >
|
||||
inline
|
||||
typename K::FT
|
||||
|
|
@ -413,6 +425,18 @@ compare_power_distance(const typename K::Point_3 &r,
|
|||
return k.compare_power_distance_3_object()(r, p, q);
|
||||
}
|
||||
|
||||
template < class K >
|
||||
inline
|
||||
typename K::Comparison_result
|
||||
compare_slope(const typename K::Point_3 &p,
|
||||
const typename K::Point_3 &q,
|
||||
const typename K::Point_3 &r,
|
||||
const typename K::Point_3 &s,
|
||||
const K& k)
|
||||
{
|
||||
return k.compare_slope_3_object()(p, q, r, s);
|
||||
}
|
||||
|
||||
template < class K >
|
||||
inline
|
||||
typename K::Comparison_result
|
||||
|
|
|
|||
|
|
@ -126,6 +126,8 @@ CGAL_Kernel_pred_RT(Compare_power_distance_3,
|
|||
compare_power_distance_3_object)
|
||||
CGAL_Kernel_pred(Compare_slope_2,
|
||||
compare_slope_2_object)
|
||||
CGAL_Kernel_pred(Compare_slope_3,
|
||||
compare_slope_3_object)
|
||||
CGAL_Kernel_pred(Compare_squared_distance_2,
|
||||
compare_squared_distance_2_object)
|
||||
CGAL_Kernel_pred(Compare_squared_distance_3,
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ _test_angle(const R&)
|
|||
typedef CGAL::Point_3<R> Point_3;
|
||||
|
||||
typedef CGAL::Vector_2<R> Vector_2;
|
||||
typedef CGAL::Vector_3<R> Vector_3;
|
||||
|
||||
Point_2 p(RT(2),RT(1));
|
||||
Point_2 q(RT(5),RT(4));
|
||||
|
|
@ -67,6 +68,12 @@ _test_angle(const R&)
|
|||
assert( CGAL::angle( org3 - sz, sz - sy) == CGAL::OBTUSE );
|
||||
assert( CGAL::angle( org3 - sx, sy - sx) == CGAL::ACUTE );
|
||||
|
||||
Vector_3 vz(RT0, RT0, RT1);
|
||||
Vector_3 vcoplanar(RT1, RT1, RT0);
|
||||
Vector_3 vmz(RT0, RT0, -RT1);
|
||||
assert( CGAL::angle( org3, sx, sy, vz) == CGAL::ACUTE );
|
||||
assert( CGAL::angle( org3, sx, sy, vcoplanar) == CGAL::RIGHT );
|
||||
assert( CGAL::angle( org3, sx, sy, vmz) == CGAL::OBTUSE );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -93,36 +93,36 @@ _test_fct_line_2(const R& )
|
|||
Line_2 l2(p3, p2);
|
||||
Line_2 l3(p4, p6);
|
||||
|
||||
assert( CGAL::compare_slopes(l1,l2) == CGAL::EQUAL );
|
||||
assert( CGAL::compare_slopes(l1,l3) == CGAL::EQUAL );
|
||||
assert( CGAL::compare_slopes(l3,l1) == CGAL::EQUAL );
|
||||
assert( CGAL::compare_slope(l1,l2) == CGAL::EQUAL );
|
||||
assert( CGAL::compare_slope(l1,l3) == CGAL::EQUAL );
|
||||
assert( CGAL::compare_slope(l3,l1) == CGAL::EQUAL );
|
||||
|
||||
std::cout <<'.';
|
||||
|
||||
// horizontal lines
|
||||
Line_2 l4(p3, p8);
|
||||
Line_2 l5(p4, p9);
|
||||
assert( CGAL::compare_slopes(l4, l5) == CGAL::EQUAL );
|
||||
assert( CGAL::compare_slopes(l3, l4) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slopes(l4, l3) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slope(l4, l5) == CGAL::EQUAL );
|
||||
assert( CGAL::compare_slope(l3, l4) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slope(l4, l3) == CGAL::SMALLER );
|
||||
|
||||
std::cout <<'.';
|
||||
|
||||
// parallel lines
|
||||
Line_2 l5a(p6, p7);
|
||||
Line_2 l5b(p11, p1);
|
||||
assert( CGAL::compare_slopes(l5a, l5b) == CGAL::EQUAL );
|
||||
assert( CGAL::compare_slope(l5a, l5b) == CGAL::EQUAL );
|
||||
assert( CGAL::parallel(l5a, l5b) );
|
||||
|
||||
// two positive slopes
|
||||
Line_2 l6(p2, p4);
|
||||
Line_2 l7(p2, p6);
|
||||
Line_2 l8(p7, p10);
|
||||
assert( CGAL::compare_slopes(l6, l6) == CGAL::EQUAL );
|
||||
assert( CGAL::compare_slopes(l6, l7) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slopes(l7, l6) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slopes(l6, l8) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slopes(l8, l6) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slope(l6, l6) == CGAL::EQUAL );
|
||||
assert( CGAL::compare_slope(l6, l7) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slope(l7, l6) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slope(l6, l8) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slope(l8, l6) == CGAL::SMALLER );
|
||||
assert( CGAL::parallel(l6, l6) );
|
||||
assert( ! CGAL::parallel(l6, l7) );
|
||||
assert( ! CGAL::parallel(l7, l6) );
|
||||
|
|
@ -130,14 +130,14 @@ _test_fct_line_2(const R& )
|
|||
assert( ! CGAL::parallel(l8, l6) );
|
||||
|
||||
// vertical and positive slope
|
||||
assert( CGAL::compare_slopes(l1, l6) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slopes(l6, l1) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slope(l1, l6) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slope(l6, l1) == CGAL::SMALLER );
|
||||
assert( ! CGAL::parallel(l1, l6) );
|
||||
assert( ! CGAL::parallel(l6, l1) );
|
||||
|
||||
// horizontal and positive slope
|
||||
assert( CGAL::compare_slopes(l5, l6) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slopes(l6, l5) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slope(l5, l6) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slope(l6, l5) == CGAL::LARGER );
|
||||
assert( ! CGAL::parallel(l5, l6) );
|
||||
assert( ! CGAL::parallel(l6, l5) );
|
||||
|
||||
|
|
@ -148,28 +148,28 @@ _test_fct_line_2(const R& )
|
|||
Line_2 l10(p9, p8);
|
||||
Line_2 l11(p5, p3);
|
||||
|
||||
assert( CGAL::compare_slopes(l9, l10) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slopes(l10, l9) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slopes(l11, l10) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slope(l9, l10) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slope(l10, l9) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slope(l11, l10) == CGAL::LARGER );
|
||||
assert( ! CGAL::parallel(l9, l10) );
|
||||
assert( ! CGAL::parallel(l10, l9) );
|
||||
assert( ! CGAL::parallel(l11, l10) );
|
||||
|
||||
// vertical and negative slope
|
||||
assert( CGAL::compare_slopes(l2, l9) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slopes(l9, l2) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slope(l2, l9) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slope(l9, l2) == CGAL::SMALLER );
|
||||
assert( ! CGAL::parallel(l2, l9) );
|
||||
assert( ! CGAL::parallel(l9, l2) );
|
||||
|
||||
// horizontal and negative slope
|
||||
assert( CGAL::compare_slopes(l5, l9) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slopes(l9, l5) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slope(l5, l9) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slope(l9, l5) == CGAL::SMALLER );
|
||||
|
||||
std::cout <<'.';
|
||||
|
||||
// positive and negative slope
|
||||
assert( CGAL::compare_slopes(l6, l9) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slopes(l9, l7) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slope(l6, l9) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slope(l9, l7) == CGAL::SMALLER );
|
||||
assert( ! CGAL::parallel(l6, l9) );
|
||||
assert( ! CGAL::parallel(l9, l7) );
|
||||
|
||||
|
|
|
|||
|
|
@ -233,6 +233,21 @@ _test_fct_point_3(const R& )
|
|||
assert( CGAL::compare_squared_radius(p0, p1, p2, p3, four) == CGAL::EQUAL );
|
||||
}
|
||||
|
||||
{
|
||||
CGAL::Point_3<R> p0(0,0,1), p1(0,0,2), p2(1,0,1), p3(1,0,2), p4(1,0,3);
|
||||
assert( CGAL::compare_slope(p0, p2, p1, p3) == CGAL::EQUAL );
|
||||
assert( CGAL::compare_slope(p0, p2, p0, p3) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slope(p0, p2, p1, p2) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slope(p0, p3, p0, p2) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slope(p0, p3, p0, p4) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slope(p0, p3, p1, p2) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slope(p1, p2, p0, p2) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slope(p1, p2, p0, p3) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slope(p1, p2, p4, p0) == CGAL::LARGER );
|
||||
|
||||
}
|
||||
|
||||
|
||||
assert(CGAL::l_infinity_distance(p1,p2) == FT(11));
|
||||
assert(CGAL::l_infinity_distance(p1,p5) == FT(6));
|
||||
// More tests, that require sqrt().
|
||||
|
|
|
|||
|
|
@ -51,43 +51,43 @@ _test_fct_segment_2(const R& )
|
|||
Segment_2 l2(p3, p2);
|
||||
Segment_2 l3(p4, p6);
|
||||
|
||||
assert( CGAL::compare_slopes(l1,l2) == CGAL::EQUAL );
|
||||
assert( CGAL::compare_slopes(l1,l3) == CGAL::EQUAL );
|
||||
assert( CGAL::compare_slopes(l3,l1) == CGAL::EQUAL );
|
||||
assert( CGAL::compare_slope(l1,l2) == CGAL::EQUAL );
|
||||
assert( CGAL::compare_slope(l1,l3) == CGAL::EQUAL );
|
||||
assert( CGAL::compare_slope(l3,l1) == CGAL::EQUAL );
|
||||
|
||||
std::cout <<'.';
|
||||
|
||||
// horizontal segments
|
||||
Segment_2 l4(p3, p8);
|
||||
Segment_2 l5(p4, p9);
|
||||
assert( CGAL::compare_slopes(l4, l5) == CGAL::EQUAL );
|
||||
assert( CGAL::compare_slopes(l3, l4) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slopes(l4, l3) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slope(l4, l5) == CGAL::EQUAL );
|
||||
assert( CGAL::compare_slope(l3, l4) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slope(l4, l3) == CGAL::SMALLER );
|
||||
|
||||
std::cout <<'.';
|
||||
|
||||
// parallel segments
|
||||
Segment_2 l5a(p6, p7);
|
||||
Segment_2 l5b(p11, p1);
|
||||
assert( CGAL::compare_slopes(l5a, l5b) == CGAL::EQUAL );
|
||||
assert( CGAL::compare_slope(l5a, l5b) == CGAL::EQUAL );
|
||||
|
||||
// two positive slopes
|
||||
// two positive slope
|
||||
Segment_2 l6(p2, p4);
|
||||
Segment_2 l7(p2, p6);
|
||||
Segment_2 l8(p7, p10);
|
||||
assert( CGAL::compare_slopes(l6, l6) == CGAL::EQUAL );
|
||||
assert( CGAL::compare_slopes(l6, l7) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slopes(l7, l6) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slopes(l6, l8) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slopes(l8, l6) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slope(l6, l6) == CGAL::EQUAL );
|
||||
assert( CGAL::compare_slope(l6, l7) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slope(l7, l6) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slope(l6, l8) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slope(l8, l6) == CGAL::SMALLER );
|
||||
|
||||
// vertical and positive slope
|
||||
assert( CGAL::compare_slopes(l1, l6) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slopes(l6, l1) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slope(l1, l6) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slope(l6, l1) == CGAL::SMALLER );
|
||||
|
||||
// horizontal and positive slope
|
||||
assert( CGAL::compare_slopes(l5, l6) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slopes(l6, l5) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slope(l5, l6) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slope(l6, l5) == CGAL::LARGER );
|
||||
|
||||
|
||||
|
||||
|
|
@ -98,23 +98,23 @@ _test_fct_segment_2(const R& )
|
|||
Segment_2 l10(p9, p8);
|
||||
Segment_2 l11(p5, p3);
|
||||
|
||||
assert( CGAL::compare_slopes(l9, l10) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slopes(l10, l9) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slopes(l11, l10) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slope(l9, l10) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slope(l10, l9) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slope(l11, l10) == CGAL::LARGER );
|
||||
|
||||
// vertical and negative slope
|
||||
assert( CGAL::compare_slopes(l2, l9) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slopes(l9, l2) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slope(l2, l9) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slope(l9, l2) == CGAL::SMALLER );
|
||||
|
||||
// horizontal and negative slope
|
||||
assert( CGAL::compare_slopes(l5, l9) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slopes(l9, l5) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slope(l5, l9) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slope(l9, l5) == CGAL::SMALLER );
|
||||
|
||||
std::cout <<'.';
|
||||
|
||||
// positive and negative slope
|
||||
assert( CGAL::compare_slopes(l6, l9) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slopes(l9, l7) == CGAL::SMALLER );
|
||||
assert( CGAL::compare_slope(l6, l9) == CGAL::LARGER );
|
||||
assert( CGAL::compare_slope(l9, l7) == CGAL::SMALLER );
|
||||
|
||||
std::cout << "done" << std::endl;
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ bool recursive_does_bound_a_volume(const TriangleMesh& tm,
|
|||
typedef Side_of_triangle_mesh<TriangleMesh, Kernel, Vpm> Side_of_tm;
|
||||
// first check that the orientation of the current cc is consistant with its
|
||||
// parent cc containing it
|
||||
bool new_is_parent_outward_oriented = internal::is_outward_oriented<Kernel>(
|
||||
bool new_is_parent_outward_oriented = internal::is_outward_oriented(
|
||||
xtrm_vertices[xtrm_cc_id], tm, parameters::vertex_point_map(vpm));
|
||||
if (new_is_parent_outward_oriented==is_parent_outward_oriented)
|
||||
return false;
|
||||
|
|
@ -91,8 +91,8 @@ bool recursive_does_bound_a_volume(const TriangleMesh& tm,
|
|||
for (std::size_t i=1;i<nb_candidates;++i)
|
||||
{
|
||||
std::size_t candidate = cc_inside[i];
|
||||
if(get(vpm,xtrm_vertices[candidate]) <
|
||||
get(vpm,xtrm_vertices[new_xtrm_cc_id])) new_xtrm_cc_id=candidate;
|
||||
if(get(vpm,xtrm_vertices[candidate]).z() >
|
||||
get(vpm,xtrm_vertices[new_xtrm_cc_id]).z()) new_xtrm_cc_id=candidate;
|
||||
new_cc_handled.reset(candidate);
|
||||
cc_handled.set(candidate);
|
||||
}
|
||||
|
|
@ -111,7 +111,7 @@ bool recursive_does_bound_a_volume(const TriangleMesh& tm,
|
|||
candidate < cc_not_handled.npos;
|
||||
candidate = cc_not_handled.find_next(candidate))
|
||||
{
|
||||
if(get(vpm,xtrm_vertices[candidate]) < get(vpm,xtrm_vertices[new_xtrm_cc_id]))
|
||||
if(get(vpm,xtrm_vertices[candidate]).z() > get(vpm,xtrm_vertices[new_xtrm_cc_id]).z())
|
||||
new_xtrm_cc_id = candidate;
|
||||
}
|
||||
|
||||
|
|
@ -129,7 +129,7 @@ bool recursive_does_bound_a_volume(const TriangleMesh& tm,
|
|||
*
|
||||
* @tparam TriangleMesh a model of `MutableFaceGraph`, `HalfedgeListGraph` and `FaceListGraph`.
|
||||
* If `TriangleMesh` has an internal property map for `CGAL::face_index_t`,
|
||||
* as a named parameter, then it must initialized.
|
||||
* as a named parameter, then it must be initialized.
|
||||
* @tparam NamedParameters a sequence of \ref namedparameters
|
||||
*
|
||||
* @param tm a triangulated surface mesh
|
||||
|
|
@ -182,7 +182,7 @@ bool does_bound_a_volume(const TriangleMesh& tm, const NamedParameters& np)
|
|||
|
||||
boost::dynamic_bitset<> cc_handled(nb_cc, 0);
|
||||
|
||||
// extract the less-xyz vertex of each connected component
|
||||
// extract a vertex with max z coordinate for each connected component
|
||||
std::vector<vertex_descriptor> xtrm_vertices(nb_cc, GT::null_vertex());
|
||||
BOOST_FOREACH(vertex_descriptor vd, vertices(tm))
|
||||
{
|
||||
|
|
@ -190,18 +190,18 @@ bool does_bound_a_volume(const TriangleMesh& tm, const NamedParameters& np)
|
|||
if (xtrm_vertices[cc_id]==GT::null_vertex())
|
||||
xtrm_vertices[cc_id]=vd;
|
||||
else
|
||||
if (get(vpm, vd)<get(vpm,xtrm_vertices[cc_id]))
|
||||
if (get(vpm, vd).z()>get(vpm,xtrm_vertices[cc_id]).z())
|
||||
xtrm_vertices[cc_id]=vd;
|
||||
}
|
||||
|
||||
//extract the less-xyz of all components
|
||||
//extract a vertex with max z amongst all components
|
||||
std::size_t xtrm_cc_id=0;
|
||||
for(std::size_t id=1; id<nb_cc; ++id)
|
||||
if (get(vpm, xtrm_vertices[id])<get(vpm,xtrm_vertices[xtrm_cc_id]))
|
||||
if (get(vpm, xtrm_vertices[id]).z()>get(vpm,xtrm_vertices[xtrm_cc_id]).z())
|
||||
xtrm_cc_id=id;
|
||||
|
||||
bool is_parent_outward_oriented =
|
||||
!internal::is_outward_oriented<Kernel>(xtrm_vertices[xtrm_cc_id], tm, np);
|
||||
!internal::is_outward_oriented(xtrm_vertices[xtrm_cc_id], tm, np);
|
||||
|
||||
return internal::recursive_does_bound_a_volume<Kernel>(tm, vpm, fid_map,
|
||||
xtrm_vertices,
|
||||
|
|
@ -433,7 +433,7 @@ boolean_operation( TriangleMesh& tm1,
|
|||
*
|
||||
* @tparam TriangleMesh a model of `MutableFaceGraph`, `HalfedgeListGraph` and `FaceListGraph`.
|
||||
* If `TriangleMesh` has an internal property map for `CGAL::face_index_t`,
|
||||
* as a named parameter, then it must initialized.
|
||||
* as a named parameter, then it must be initialized.
|
||||
*
|
||||
* @tparam NamedParameters1 a sequence of \ref namedparameters
|
||||
* @tparam NamedParameters2 a sequence of \ref namedparameters
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include <CGAL/Polygon_mesh_processing/compute_normal.h>
|
||||
#include <CGAL/Polygon_mesh_processing/internal/named_function_params.h>
|
||||
#include <CGAL/Polygon_mesh_processing/internal/named_params_helper.h>
|
||||
#include <CGAL/Projection_traits_xy_3.h>
|
||||
#include <CGAL/boost/graph/helpers.h>
|
||||
#include <CGAL/boost/graph/iterator.h>
|
||||
|
||||
|
|
@ -40,37 +41,100 @@ namespace CGAL {
|
|||
namespace Polygon_mesh_processing {
|
||||
|
||||
namespace internal{
|
||||
template <class Less_xyz, class VPmap>
|
||||
struct Compare_vertex_points_xyz_3{
|
||||
Less_xyz less;
|
||||
VPmap vpmap;
|
||||
|
||||
Compare_vertex_points_xyz_3(VPmap const& vpmap)
|
||||
: vpmap(vpmap){}
|
||||
template <class GT, class VPmap>
|
||||
struct Compare_vertex_points_z_3
|
||||
{
|
||||
VPmap vpmap;
|
||||
typename GT::Compare_z_3 compare_z;
|
||||
|
||||
Compare_vertex_points_z_3(VPmap const& vpmap, const GT& gt)
|
||||
: vpmap(vpmap)
|
||||
, compare_z(gt.compare_z_3_object())
|
||||
{}
|
||||
|
||||
typedef bool result_type;
|
||||
template <class vertex_descriptor>
|
||||
bool operator()(vertex_descriptor v1, vertex_descriptor v2) const
|
||||
{
|
||||
return less(get(vpmap, v1), get(vpmap, v2));
|
||||
return CGAL::SMALLER == compare_z(get(vpmap, v1), get(vpmap, v2));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename Kernel, typename PM, typename NamedParameters>
|
||||
bool is_outward_oriented(typename boost::graph_traits<PM>::vertex_descriptor vd,
|
||||
const PM& pmesh,
|
||||
|
||||
template<typename PolygonMesh, typename NamedParameters>
|
||||
bool is_outward_oriented(typename boost::graph_traits<PolygonMesh>::vertex_descriptor v_max,
|
||||
const PolygonMesh& pmesh,
|
||||
const NamedParameters& np)
|
||||
{
|
||||
const typename Kernel::Vector_3&
|
||||
normal_v_min = compute_vertex_normal(vd, pmesh, np);
|
||||
using boost::choose_param;
|
||||
using boost::get_param;
|
||||
|
||||
return normal_v_min[0] < 0 || (
|
||||
normal_v_min[0] == 0 && (
|
||||
normal_v_min[1] < 0 ||
|
||||
( normal_v_min[1]==0 && normal_v_min[2] < 0 )
|
||||
)
|
||||
);
|
||||
//VertexPointMap
|
||||
typedef typename GetVertexPointMap<PolygonMesh, NamedParameters>::const_type VPMap;
|
||||
VPMap vpmap = choose_param(get_param(np, vertex_point),
|
||||
get_const_property_map(vertex_point, pmesh));
|
||||
//Kernel
|
||||
typedef typename GetGeomTraits<PolygonMesh, NamedParameters>::type GT;
|
||||
GT gt = choose_param(get_param(np, geom_traits), GT());
|
||||
|
||||
//among the incoming edges of `v_max`, find one edge `e` with the minimal slope
|
||||
typedef typename boost::graph_traits<PolygonMesh>::halfedge_descriptor halfedge_descriptor;
|
||||
halfedge_descriptor min_slope_he = halfedge(v_max, pmesh);
|
||||
CGAL_assertion(v_max == target(min_slope_he, pmesh));
|
||||
|
||||
typename GT::Compare_slope_3 compare_slope = gt.compare_slope_3_object();
|
||||
BOOST_FOREACH(halfedge_descriptor he, halfedges_around_target(v_max, pmesh))
|
||||
{
|
||||
CGAL_assertion(v_max == target(min_slope_he, pmesh));
|
||||
CGAL_assertion(v_max == target(he, pmesh));
|
||||
|
||||
if(CGAL::SMALLER == compare_slope(get(vpmap, source(he, pmesh)),
|
||||
get(vpmap, v_max),
|
||||
get(vpmap, source(min_slope_he, pmesh)),
|
||||
get(vpmap, v_max)))
|
||||
{
|
||||
min_slope_he = he;
|
||||
}
|
||||
}
|
||||
|
||||
// We compute the orientations of the two triangles incident to the edge
|
||||
// of `min_slope_he` projected in the xy-plane. We can conclude using
|
||||
// the 2D orientation of the 3D triangle that is the top one along the z-axis
|
||||
// in the neighborhood of `min_slope_he`.
|
||||
Projection_traits_xy_3<GT> p_gt;
|
||||
typename Projection_traits_xy_3<GT>::Orientation_2 orientation_2 = p_gt.orientation_2_object();
|
||||
|
||||
typename boost::property_traits<VPMap>::reference p1 = get(vpmap, source(min_slope_he, pmesh));
|
||||
typename boost::property_traits<VPMap>::reference p2 = get(vpmap, target(min_slope_he, pmesh));
|
||||
typename boost::property_traits<VPMap>::reference p3 = get(vpmap, target(next(min_slope_he, pmesh), pmesh));
|
||||
typename boost::property_traits<VPMap>::reference p4 = get(vpmap, target(next(opposite(min_slope_he, pmesh), pmesh), pmesh));
|
||||
|
||||
Orientation p1p2p3_2d = orientation_2(p1, p2, p3);
|
||||
Orientation p2p1p4_2d = orientation_2(p2, p1, p4);
|
||||
|
||||
CGAL_assertion( p1p2p3_2d!=COLLINEAR || p2p1p4_2d!=COLLINEAR ); // no self-intersection
|
||||
|
||||
if ( p1p2p3_2d == COLLINEAR)
|
||||
return p2p1p4_2d == LEFT_TURN;
|
||||
if (p2p1p4_2d ==COLLINEAR)
|
||||
return p1p2p3_2d == LEFT_TURN;
|
||||
|
||||
// if the local dihedral angle is strictly larger that PI/2, we can conclude with any of two triangles
|
||||
if (p1p2p3_2d==p2p1p4_2d)
|
||||
return p1p2p3_2d == LEFT_TURN;
|
||||
|
||||
typename GT::Orientation_3 orientation_3 = gt.orientation_3_object();
|
||||
|
||||
CGAL_assertion( orientation_3(p1, p2, p3, p4) != COPLANAR ); // same side of min_slope_he and no self-intersection
|
||||
|
||||
// if p1p2p3_2d is left turn, then it must be the top face so that the orientation is outward oriented
|
||||
if (p1p2p3_2d == LEFT_TURN)
|
||||
return orientation_3(p1, p2, p3, p4) == NEGATIVE;
|
||||
|
||||
// same test with the other face
|
||||
CGAL_assertion(p2p1p4_2d == LEFT_TURN);
|
||||
return orientation_3(p2, p1, p4, p3) == NEGATIVE;
|
||||
}
|
||||
} // end of namespace internal
|
||||
|
||||
|
|
@ -109,6 +173,11 @@ bool is_outward_oriented(const PolygonMesh& pmesh,
|
|||
CGAL_warning(CGAL::is_closed(pmesh));
|
||||
CGAL_precondition(CGAL::is_valid(pmesh));
|
||||
|
||||
//check for empty pmesh
|
||||
CGAL_warning(faces(pmesh).first != faces(pmesh).second);
|
||||
if (faces(pmesh).first == faces(pmesh).second)
|
||||
return true;
|
||||
|
||||
using boost::choose_param;
|
||||
using boost::get_param;
|
||||
|
||||
|
|
@ -117,17 +186,19 @@ bool is_outward_oriented(const PolygonMesh& pmesh,
|
|||
VPMap vpmap = choose_param(get_param(np, vertex_point),
|
||||
get_const_property_map(vertex_point, pmesh));
|
||||
//Kernel
|
||||
typedef typename GetGeomTraits<PolygonMesh, NamedParameters>::type Kernel;
|
||||
|
||||
internal::Compare_vertex_points_xyz_3<typename Kernel::Less_xyz_3, VPMap >
|
||||
less_xyz(vpmap);
|
||||
typedef typename GetGeomTraits<PolygonMesh, NamedParameters>::type GT;
|
||||
GT gt = choose_param(get_param(np, geom_traits), GT());
|
||||
|
||||
//find the vertex with maximal z coordinate
|
||||
typename boost::graph_traits<PolygonMesh>::vertex_iterator vbegin, vend;
|
||||
cpp11::tie(vbegin, vend) = vertices(pmesh);
|
||||
typename boost::graph_traits<PolygonMesh>::vertex_iterator v_min
|
||||
= std::min_element(vbegin, vend, less_xyz);
|
||||
|
||||
return internal::is_outward_oriented<Kernel>(*v_min, pmesh, np);
|
||||
internal::Compare_vertex_points_z_3<GT, VPMap> less_z(vpmap, gt);
|
||||
typename boost::graph_traits<PolygonMesh>::vertex_iterator v_max_it
|
||||
= std::max_element(vbegin, vend, less_z);
|
||||
typename boost::graph_traits<PolygonMesh>::vertex_descriptor v_max = *v_max_it;
|
||||
|
||||
return internal::is_outward_oriented(v_max, pmesh, np);
|
||||
}
|
||||
|
||||
///\cond SKIP_IN_MANUAL
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
OFF
|
||||
4 4 0
|
||||
|
||||
0 0 0
|
||||
0.65000000000000002 -1.3 0.65000000000000002
|
||||
0.10000000000000001 -1 1
|
||||
2 -2 -0.5
|
||||
3 2 1 0
|
||||
3 1 3 0
|
||||
3 3 2 0
|
||||
3 3 1 2
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
OFF
|
||||
4 4 0
|
||||
|
||||
0 0 0
|
||||
0.65000000000000002 -1.3 0.65000000000000002
|
||||
0.10000000000000001 -1 1
|
||||
-0.33420955685098419 -0.59067608503190883 0.55877066363146466
|
||||
3 2 1 0
|
||||
3 1 3 0
|
||||
3 3 2 0
|
||||
3 3 1 2
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
OFF
|
||||
4 4 0
|
||||
|
||||
0 1 0
|
||||
1 0 0
|
||||
0 0 0
|
||||
0 0 1
|
||||
3 0 1 2
|
||||
3 2 3 0
|
||||
3 1 3 2
|
||||
3 0 3 1
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
OFF
|
||||
4 4 0
|
||||
|
||||
0 0 1
|
||||
0 1 0.8
|
||||
-1 1 0.9
|
||||
1 0 0.5
|
||||
|
||||
3 0 1 2
|
||||
3 0 2 3
|
||||
3 0 3 1
|
||||
3 1 3 2
|
||||
|
|
@ -61,6 +61,12 @@ int main()
|
|||
{
|
||||
|
||||
test_orient<Epic>("data/elephant.off");
|
||||
test_orient<Epic>("data-coref/cube.off");
|
||||
test_orient<Epic>("data/tetra1.off");
|
||||
test_orient<Epic>("data/tetra2.off");
|
||||
test_orient<Epic>("data/tetra3.off");
|
||||
test_orient<Epic>("data/tetra4.off");
|
||||
test_orient<Epic>("data-coref/cube.off");
|
||||
test_orient<Epec>("data/elephant.off");
|
||||
|
||||
std::cerr << "All done." << std::endl;
|
||||
|
|
|
|||
Loading…
Reference in New Issue