From 83d7a89f22585a2da956b411bcd1817c80908f49 Mon Sep 17 00:00:00 2001 From: Giles Bathgate Date: Fri, 29 Jan 2021 17:32:05 +0000 Subject: [PATCH 1/5] Calculate normals for facets more efficiently --- Nef_3/include/CGAL/normal_vector_newell_3.h | 100 +++++++++++++++----- 1 file changed, 78 insertions(+), 22 deletions(-) diff --git a/Nef_3/include/CGAL/normal_vector_newell_3.h b/Nef_3/include/CGAL/normal_vector_newell_3.h index 282f8e5b5cb..5e34f350d33 100644 --- a/Nef_3/include/CGAL/normal_vector_newell_3.h +++ b/Nef_3/include/CGAL/normal_vector_newell_3.h @@ -23,6 +23,8 @@ #undef CGAL_NEF_DEBUG #define CGAL_NEF_DEBUG 79 #include +#include +#include namespace CGAL { @@ -30,32 +32,74 @@ namespace internal_nef { template 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::Kernel::RT RT; + const RT& phw = p.hw(); + const RT& qhw = q.hw(); + const RT& nhw = n.hw(); + const RT& sq = phw * phw * qhw * 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.hx() - * p.hw() * p.hw() - * q.hw() * q.hw() - + n.hw() - * ( p.hy() * q.hw() - q.hy() * p.hw()) - * ( p.hz() * q.hw() + q.hz() * p.hw()), + * sq + + nhw + * ( phyqhw - qhyphw ) + * ( phzqhw + qhzphw ), n.hy() - * p.hw() * p.hw() - * q.hw() * q.hw() - + n.hw() - * ( p.hz() * q.hw() - q.hz() * p.hw()) - * ( p.hx() * q.hw() + q.hx() * p.hw()), + * sq + + nhw + * ( phzqhw - qhzphw ) + * ( phxqhw + qhxphw ), n.hz() - * p.hw() * p.hw() - * q.hw() * q.hw() - + n.hw() - * ( p.hx() * q.hw() - q.hx() * p.hw()) - * ( p.hy() * q.hw() + q.hy() * p.hw()), + * sq + + nhw + * ( phxqhw - qhxphw ) + * ( phyqhw + qhyphw ), n.hw() - * p.hw() * p.hw() - * q.hw() * q.hw() + * sq ); } + +template +CGAL_MEDIUM_INLINE +void newell_single_step_3( const Handle& p, const Handle& q, Vector& n, const Cartesian_tag&) +{ + typedef typename Kernel_traits::Kernel::FT FT; + const FT& phy = p.hy(); + const FT& qhy = q.hy(); + const FT& phx = p.hx(); + const FT& qhx = q.hx(); + const FT& phz = p.hz(); + const FT& qhz = q.hz(); + + n = Vector( + n.hx() + + ( phy - qhy ) + * ( phz + qhz ), + n.hy() + + ( phz - qhz ) + * ( phx + qhx ), + n.hz() + + ( phx - qhx ) + * ( phy + qhy ) + ); +} + +template +bool is_triangle_3( const IC& first ) +{ + IC last(first); + ++last; ++last; ++last; + return first==last; +} + } template @@ -70,6 +114,12 @@ void normal_vector_newell_3( IC first, IC last, Vector& n ) // three. { CGAL_assertion( !CGAL::is_empty_range( first, last)); + if(internal_nef::is_triangle_3(first)) { + n = orthogonal_vector(*first,*(++first),*(++first)); + return; + } + + typedef typename Kernel_traits::Kernel R; // Compute facet normals via the Newell-method as described in // Filippo Tampieri: Newell's Method for Computing the Plane // 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; ++first; 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; ++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 "< void normal_vector_newell_3( IC first, IC last, VertexPointMap vpm, Vector& n ) { CGAL_assertion( !CGAL::is_empty_range( first, last)); + if(internal_nef::is_triangle_3(first)) { + n = orthogonal_vector(get(vpm,*first),get(vpm,*(++first)),get(vpm,*(++first))); + return; + } + + typedef typename Kernel_traits::Kernel R; // Compute facet normals via the Newell-method as described in // Filippo Tampieri: Newell's Method for Computing the Plane // Equation of a Polygon. Graphics Gems III, David Kirk, @@ -102,11 +158,11 @@ void normal_vector_newell_3( IC first, IC last, VertexPointMap vpm, Vector& n ) IC prev = first; ++first; 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; ++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 "< Date: Sat, 30 Jan 2021 11:36:41 +0000 Subject: [PATCH 2/5] Improvements to normal vector newell after review --- Nef_3/include/CGAL/normal_vector_newell_3.h | 32 ++++++++++----------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Nef_3/include/CGAL/normal_vector_newell_3.h b/Nef_3/include/CGAL/normal_vector_newell_3.h index 5e34f350d33..2735532899a 100644 --- a/Nef_3/include/CGAL/normal_vector_newell_3.h +++ b/Nef_3/include/CGAL/normal_vector_newell_3.h @@ -38,7 +38,7 @@ void newell_single_step_3( const Handle& p, const Handle& q, Vector& n, const Ho const RT& phw = p.hw(); const RT& qhw = q.hw(); const RT& nhw = n.hw(); - const RT& sq = phw * phw * qhw * qhw; + 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; @@ -72,23 +72,23 @@ CGAL_MEDIUM_INLINE void newell_single_step_3( const Handle& p, const Handle& q, Vector& n, const Cartesian_tag&) { typedef typename Kernel_traits::Kernel::FT FT; - const FT& phy = p.hy(); - const FT& qhy = q.hy(); - const FT& phx = p.hx(); - const FT& qhx = q.hx(); - const FT& phz = p.hz(); - const FT& qhz = q.hz(); + 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.hx() - + ( phy - qhy ) - * ( phz + qhz ), - n.hy() - + ( phz - qhz ) - * ( phx + qhx ), - n.hz() - + ( phx - qhx ) - * ( phy + qhy ) + n.x() + + ( py - qy ) + * ( pz + qz ), + n.y() + + ( pz - qz ) + * ( px + qx ), + n.z() + + ( px - qx ) + * ( py + qy ) ); } From e87432f257ba49c5591e6820c42b9738324f235c Mon Sep 17 00:00:00 2001 From: Giles Bathgate Date: Tue, 2 Feb 2021 08:14:32 +0000 Subject: [PATCH 3/5] Use std:next for is_triangle_3 in normal vector newell Co-authored-by: Sebastien Loriot --- Nef_3/include/CGAL/normal_vector_newell_3.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Nef_3/include/CGAL/normal_vector_newell_3.h b/Nef_3/include/CGAL/normal_vector_newell_3.h index 2735532899a..95810d73e7e 100644 --- a/Nef_3/include/CGAL/normal_vector_newell_3.h +++ b/Nef_3/include/CGAL/normal_vector_newell_3.h @@ -95,9 +95,7 @@ void newell_single_step_3( const Handle& p, const Handle& q, Vector& n, const Ca template bool is_triangle_3( const IC& first ) { - IC last(first); - ++last; ++last; ++last; - return first==last; + return std::next(first,3) == first; } } From 6335c1068c69ba63cee0f97e8ee5e4222ba06dd4 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 10 Feb 2021 10:53:37 +0000 Subject: [PATCH 4/5] Advance copies of the iterator --- Nef_3/include/CGAL/normal_vector_newell_3.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Nef_3/include/CGAL/normal_vector_newell_3.h b/Nef_3/include/CGAL/normal_vector_newell_3.h index 95810d73e7e..195144f0f4a 100644 --- a/Nef_3/include/CGAL/normal_vector_newell_3.h +++ b/Nef_3/include/CGAL/normal_vector_newell_3.h @@ -112,11 +112,13 @@ void normal_vector_newell_3( IC first, IC last, Vector& n ) // three. { CGAL_assertion( !CGAL::is_empty_range( first, last)); + if(internal_nef::is_triangle_3(first)) { - n = orthogonal_vector(*first,*(++first),*(++first)); + n = orthogonal_vector(*first,*(std::next(first)),*(std__next(first,2))); return; } + typedef typename Kernel_traits::Kernel R; // Compute facet normals via the Newell-method as described in // Filippo Tampieri: Newell's Method for Computing the Plane @@ -140,11 +142,14 @@ template void normal_vector_newell_3( IC first, IC last, VertexPointMap vpm, Vector& n ) { CGAL_assertion( !CGAL::is_empty_range( first, last)); + if(internal_nef::is_triangle_3(first)) { - n = orthogonal_vector(get(vpm,*first),get(vpm,*(++first)),get(vpm,*(++first))); + + n = orthogonal_vector(get(vpm,*first),get(vpm,*(std::next(first))),get(vpm,*(std::next(first,2)))); return; } + typedef typename Kernel_traits::Kernel R; // Compute facet normals via the Newell-method as described in // Filippo Tampieri: Newell's Method for Computing the Plane From 5345986827c6435ebeef06b556ed2113419187e2 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 10 Feb 2021 11:13:14 +0000 Subject: [PATCH 5/5] Fix typo in Homogeneous case (which I hadn't tested) --- Nef_3/include/CGAL/normal_vector_newell_3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Nef_3/include/CGAL/normal_vector_newell_3.h b/Nef_3/include/CGAL/normal_vector_newell_3.h index 195144f0f4a..80874a1efa1 100644 --- a/Nef_3/include/CGAL/normal_vector_newell_3.h +++ b/Nef_3/include/CGAL/normal_vector_newell_3.h @@ -114,7 +114,7 @@ void normal_vector_newell_3( IC first, IC last, Vector& n ) 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))); + n = orthogonal_vector(*first,*(std::next(first)),*(std::next(first,2))); return; }