mirror of https://github.com/CGAL/cgal
Merge pull request #5412 from GilesBathgate/performance-calculate-normals
Calculate normals for facets more efficiently
This commit is contained in:
commit
1958c95797
|
|
@ -23,6 +23,8 @@
|
||||||
#undef CGAL_NEF_DEBUG
|
#undef CGAL_NEF_DEBUG
|
||||||
#define CGAL_NEF_DEBUG 79
|
#define CGAL_NEF_DEBUG 79
|
||||||
#include <CGAL/Nef_2/debug.h>
|
#include <CGAL/Nef_2/debug.h>
|
||||||
|
#include <CGAL/representation_tags.h>
|
||||||
|
#include <CGAL/Kernel_traits.h>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
|
|
@ -30,32 +32,72 @@ namespace internal_nef
|
||||||
{
|
{
|
||||||
template <class Handle, class Vector>
|
template <class Handle, class Vector>
|
||||||
CGAL_MEDIUM_INLINE
|
CGAL_MEDIUM_INLINE
|
||||||
void newell_single_step_3( const Handle& p, const Handle& q, Vector& n )
|
void newell_single_step_3( const Handle& p, const Handle& q, Vector& n, const Homogeneous_tag&)
|
||||||
{
|
{
|
||||||
|
typedef typename Kernel_traits<Vector>::Kernel::RT RT;
|
||||||
|
const RT& phw = p.hw();
|
||||||
|
const RT& qhw = q.hw();
|
||||||
|
const RT& nhw = n.hw();
|
||||||
|
const RT& sq = square(phw) * square(qhw);
|
||||||
|
const RT& phyqhw = p.hy() * qhw;
|
||||||
|
const RT& qhyphw = q.hy() * phw;
|
||||||
|
const RT& phxqhw = p.hx() * qhw;
|
||||||
|
const RT& qhxphw = q.hx() * phw;
|
||||||
|
const RT& phzqhw = p.hz() * qhw;
|
||||||
|
const RT& qhzphw = q.hz() * phw;
|
||||||
|
|
||||||
n = Vector(
|
n = Vector(
|
||||||
n.hx()
|
n.hx()
|
||||||
* p.hw() * p.hw()
|
* sq
|
||||||
* q.hw() * q.hw()
|
+ nhw
|
||||||
+ n.hw()
|
* ( phyqhw - qhyphw )
|
||||||
* ( p.hy() * q.hw() - q.hy() * p.hw())
|
* ( phzqhw + qhzphw ),
|
||||||
* ( p.hz() * q.hw() + q.hz() * p.hw()),
|
|
||||||
n.hy()
|
n.hy()
|
||||||
* p.hw() * p.hw()
|
* sq
|
||||||
* q.hw() * q.hw()
|
+ nhw
|
||||||
+ n.hw()
|
* ( phzqhw - qhzphw )
|
||||||
* ( p.hz() * q.hw() - q.hz() * p.hw())
|
* ( phxqhw + qhxphw ),
|
||||||
* ( p.hx() * q.hw() + q.hx() * p.hw()),
|
|
||||||
n.hz()
|
n.hz()
|
||||||
* p.hw() * p.hw()
|
* sq
|
||||||
* q.hw() * q.hw()
|
+ nhw
|
||||||
+ n.hw()
|
* ( phxqhw - qhxphw )
|
||||||
* ( p.hx() * q.hw() - q.hx() * p.hw())
|
* ( phyqhw + qhyphw ),
|
||||||
* ( p.hy() * q.hw() + q.hy() * p.hw()),
|
|
||||||
n.hw()
|
n.hw()
|
||||||
* p.hw() * p.hw()
|
* sq
|
||||||
* q.hw() * q.hw()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class Handle, class Vector>
|
||||||
|
CGAL_MEDIUM_INLINE
|
||||||
|
void newell_single_step_3( const Handle& p, const Handle& q, Vector& n, const Cartesian_tag&)
|
||||||
|
{
|
||||||
|
typedef typename Kernel_traits<Vector>::Kernel::FT FT;
|
||||||
|
const FT& py = p.y();
|
||||||
|
const FT& qy = q.y();
|
||||||
|
const FT& px = p.x();
|
||||||
|
const FT& qx = q.x();
|
||||||
|
const FT& pz = p.z();
|
||||||
|
const FT& qz = q.z();
|
||||||
|
|
||||||
|
n = Vector(
|
||||||
|
n.x()
|
||||||
|
+ ( py - qy )
|
||||||
|
* ( pz + qz ),
|
||||||
|
n.y()
|
||||||
|
+ ( pz - qz )
|
||||||
|
* ( px + qx ),
|
||||||
|
n.z()
|
||||||
|
+ ( px - qx )
|
||||||
|
* ( py + qy )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class IC>
|
||||||
|
bool is_triangle_3( const IC& first )
|
||||||
|
{
|
||||||
|
return std::next(first,3) == first;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class IC, class Vector>
|
template <class IC, class Vector>
|
||||||
|
|
@ -70,6 +112,14 @@ void normal_vector_newell_3( IC first, IC last, Vector& n )
|
||||||
// three.
|
// three.
|
||||||
{
|
{
|
||||||
CGAL_assertion( !CGAL::is_empty_range( first, last));
|
CGAL_assertion( !CGAL::is_empty_range( first, last));
|
||||||
|
|
||||||
|
if(internal_nef::is_triangle_3(first)) {
|
||||||
|
n = orthogonal_vector(*first,*(std::next(first)),*(std::next(first,2)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef typename Kernel_traits<Vector>::Kernel R;
|
||||||
// Compute facet normals via the Newell-method as described in
|
// Compute facet normals via the Newell-method as described in
|
||||||
// Filippo Tampieri: Newell's Method for Computing the Plane
|
// Filippo Tampieri: Newell's Method for Computing the Plane
|
||||||
// Equation of a Polygon. Graphics Gems III, David Kirk,
|
// Equation of a Polygon. Graphics Gems III, David Kirk,
|
||||||
|
|
@ -80,11 +130,11 @@ void normal_vector_newell_3( IC first, IC last, Vector& n )
|
||||||
IC prev = first;
|
IC prev = first;
|
||||||
++first;
|
++first;
|
||||||
while( first != last) {
|
while( first != last) {
|
||||||
internal_nef::newell_single_step_3( *prev, *first, n);
|
internal_nef::newell_single_step_3( *prev, *first, n, typename R::Kernel_tag());
|
||||||
prev = first;
|
prev = first;
|
||||||
++first;
|
++first;
|
||||||
}
|
}
|
||||||
internal_nef::newell_single_step_3( *prev, *start_point, n);
|
internal_nef::newell_single_step_3( *prev, *start_point, n, typename R::Kernel_tag());
|
||||||
CGAL_NEF_TRACEN("newell normal vector "<<n);
|
CGAL_NEF_TRACEN("newell normal vector "<<n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -92,6 +142,15 @@ template <class IC, class Vector, class VertexPointMap>
|
||||||
void normal_vector_newell_3( IC first, IC last, VertexPointMap vpm, Vector& n )
|
void normal_vector_newell_3( IC first, IC last, VertexPointMap vpm, Vector& n )
|
||||||
{
|
{
|
||||||
CGAL_assertion( !CGAL::is_empty_range( first, last));
|
CGAL_assertion( !CGAL::is_empty_range( first, last));
|
||||||
|
|
||||||
|
if(internal_nef::is_triangle_3(first)) {
|
||||||
|
|
||||||
|
n = orthogonal_vector(get(vpm,*first),get(vpm,*(std::next(first))),get(vpm,*(std::next(first,2))));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef typename Kernel_traits<Vector>::Kernel R;
|
||||||
// Compute facet normals via the Newell-method as described in
|
// Compute facet normals via the Newell-method as described in
|
||||||
// Filippo Tampieri: Newell's Method for Computing the Plane
|
// Filippo Tampieri: Newell's Method for Computing the Plane
|
||||||
// Equation of a Polygon. Graphics Gems III, David Kirk,
|
// Equation of a Polygon. Graphics Gems III, David Kirk,
|
||||||
|
|
@ -102,11 +161,11 @@ void normal_vector_newell_3( IC first, IC last, VertexPointMap vpm, Vector& n )
|
||||||
IC prev = first;
|
IC prev = first;
|
||||||
++first;
|
++first;
|
||||||
while( first != last) {
|
while( first != last) {
|
||||||
internal_nef::newell_single_step_3( get(vpm,*prev), get(vpm,*first), n);
|
internal_nef::newell_single_step_3( get(vpm,*prev), get(vpm,*first), n, typename R::Kernel_tag());
|
||||||
prev = first;
|
prev = first;
|
||||||
++first;
|
++first;
|
||||||
}
|
}
|
||||||
internal_nef::newell_single_step_3( get(vpm,*prev), get(vpm,*start_point), n);
|
internal_nef::newell_single_step_3( get(vpm,*prev), get(vpm,*start_point), n, typename R::Kernel_tag());
|
||||||
CGAL_NEF_TRACEN("newell normal vector "<<n);
|
CGAL_NEF_TRACEN("newell normal vector "<<n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue