Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
10.4.x.x (relative to 10.4.5.0)
========

Improvements
------------

- PointsPrimitive, Primitive : Accelerated bounds computation using `tbb::parallel_reduce`.

Fixes
-----

Expand Down
60 changes: 41 additions & 19 deletions src/IECoreScene/PointsPrimitive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
#include "IECore/MurmurHash.h"
#include "IECore/SimpleTypedData.h"

#include <tbb/parallel_reduce.h>
#include <tbb/blocked_range.h>

using namespace std;
using namespace Imath;
using namespace IECore;
Expand Down Expand Up @@ -193,26 +196,45 @@ Imath::Box3f PointsPrimitive::bound() const
// Compute the bounding box from the gathered data.

Box3f result;
for( size_t i = 0; i < count; ++i )
{
float r = constantWidth * *width / 2.0f;
width += widthStep;
if( aspectRatio )
{
// Type is patch - the diagonal will be
// longer than either the width or the
// height, so derive a new radius from that.
float hh = r; // half the height
if( *aspectRatio != 0.0f )
using RangeType = tbb::blocked_range< const V3f* >;
tbb::this_task_arena::isolate( [ =, & result ]{
tbb::task_group_context taskGroupContext( tbb::task_group_context::isolated );
result = tbb::parallel_reduce( RangeType( p, p + count, 1000 ), Imath::Box3f(),
[ = ]( const RangeType& range, const Imath::Box3f& value ) -> Imath::Box3f
{
hh /= *aspectRatio;
}
r = sqrtf( r * r + hh * hh );
aspectRatio += aspectRatioStep;
}
result.extendBy( Box3f( *p - V3f( r ), *p + V3f( r ) ) );
p++;
}
Imath::Box3f b( value );
const size_t offset = range.begin() - p;
const float* wIt = offset * widthStep + width;
const float* aIt = offset * aspectRatioStep + aspectRatio;
for( const V3f& pos : range )
{
float r = constantWidth * ( *wIt ) / 2.0f;
wIt += widthStep;
if( aspectRatio )
{
// Type is patch - the diagonal will be
// longer than either the width or the
// height, so derive a new radius from that.
float hh = r; // half the height
if( ( *aIt ) != 0.0f )
{
hh /= ( *aIt );
}
r = sqrtf( r * r + hh * hh );
aIt += aspectRatioStep;
}
b.extendBy( Box3f( pos - V3f( r ), pos + V3f( r ) ) );
}
return b;
},
[]( const Imath::Box3f& lhs, const Imath::Box3f& rhs ) -> Imath::Box3f
{
Imath::Box3f b( lhs );
b.extendBy( rhs );
return b;
},
taskGroupContext );
} );

return result;
}
Expand Down
28 changes: 24 additions & 4 deletions src/IECoreScene/Primitive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@

#include "boost/algorithm/string.hpp"

#include <tbb/parallel_reduce.h>
#include <tbb/blocked_range.h>

#include <cassert>

using namespace IECore;
Expand Down Expand Up @@ -78,10 +81,27 @@ Imath::Box3f Primitive::bound() const
if( p )
{
const vector<V3f> &pp = p->readable();
for( size_t i=0; i<pp.size(); i++ )
{
result.extendBy( pp[i] );
}
using RangeType = tbb::blocked_range< const V3f* >;
tbb::this_task_arena::isolate( [ & result, & pp ]{
tbb::task_group_context taskGroupContext( tbb::task_group_context::isolated );
result = tbb::parallel_reduce( RangeType( pp.data(), pp.data() + pp.size(), 1000 ), Imath::Box3f(),
[]( const RangeType& range, const Imath::Box3f& value ) -> Imath::Box3f
{
Imath::Box3f b( value );
for( const V3f& pos : range )
{
b.extendBy( pos );
}
return b;
},
[]( const Imath::Box3f& lhs, const Imath::Box3f& rhs ) -> Imath::Box3f
{
Imath::Box3f b( lhs );
b.extendBy( rhs );
return b;
},
taskGroupContext );
} );
}
}
return result;
Expand Down