@@ -170,124 +170,107 @@ struct FillVectorFromValue
170170 size_t m_len;
171171};
172172
173- // / template to dispatch only primvars which are supported by the SplitTask
173+ // / template to dispatch only primvars which are supported by splitPrimitive
174174// / Numeric & string like arrays, which contain elements which can be added to a std::set
175175template <typename T> struct IsDeletablePrimVar : boost::mpl::or_< IECore::TypeTraits::IsStringVectorTypedData<T>, IECore::TypeTraits::IsNumericVectorTypedData<T> > {};
176176
177177
178178template <typename T, typename S, typename P>
179- class SplitTask : public tbb ::task
179+ void splitPrimitive ( const std::vector<T> &segments, typename P::Ptr primitive, const S& splitter, const std::string &primvarName, std::vector< typename P::Ptr> &outputPrimitives, size_t offset, size_t depth, const IECore::Canceller *canceller, tbb::task_group_context &taskGroupContext )
180180{
181- private:
182- typedef typename P::Ptr Ptr;
183- public:
184- SplitTask (const std::vector<T> &segments, typename P::Ptr primitive, const S& splitter, const std::string &primvarName, std::vector<Ptr> &outputPrimitives, size_t offset, size_t depth, const IECore::Canceller *canceller )
185- : m_segments(segments), m_primitive(primitive), m_splitter(splitter), m_primvarName(primvarName), m_outputPrimitives( outputPrimitives ), m_offset(offset), m_depth(depth), m_canceller( canceller )
186- {
187- }
188-
189- task *execute () override
190- {
191-
192- if ( numPrimitives ( m_primitive.get () ) == 0 && !m_segments.empty () )
193- {
194- m_outputPrimitives[m_offset] = m_primitive;
195- return nullptr ;
196- }
197-
198- if ( m_segments.size () == 0 )
199- {
200- return nullptr ;
201- }
202-
203- size_t offset = m_segments.size () / 2 ;
204- typename std::vector<T>::iterator mid = m_segments.begin () + offset;
205-
206- IECoreScene::PrimitiveVariable segmentPrimVar = m_primitive->variables .find ( m_primvarName )->second ;
181+ using Ptr = typename P::Ptr;
207182
208- std::vector<T> lowerSegments (m_segments. begin (), mid);
209- std::vector<T> upperSegments (mid, m_segments. end ());
210-
211- std::set<T> lowerSegmentsSet ( m_segments. begin (), mid ) ;
212- std::set<T> upperSegmentsSet (mid, m_segments. end ());
183+ if ( numPrimitives ( primitive. get () ) == 0 && !segments. empty () )
184+ {
185+ outputPrimitives[offset] = primitive;
186+ return ;
187+ }
213188
214- const auto &readable = IECore::runTimeCast<IECore::TypedData<std::vector<T> > >( segmentPrimVar.data )->readable ();
189+ if ( segments.size () == 0 )
190+ {
191+ return ;
192+ }
215193
216- IECore::BoolVectorDataPtr deletionArrayLower = new IECore::BoolVectorData ();
217- auto &writableLower = deletionArrayLower->writable ();
194+ size_t midOffset = segments.size () / 2 ;
218195
219- IECore::BoolVectorDataPtr deletionArrayUpper = new IECore::BoolVectorData ();
220- auto &writableUpper = deletionArrayUpper->writable ();
196+ IECoreScene::PrimitiveVariable segmentPrimVar = primitive->variables .find ( primvarName )->second ;
221197
222- size_t deleteCount = 0 ;
223- if ( segmentPrimVar.indices )
224- {
225- auto &readableIndices = segmentPrimVar.indices ->readable ();
226- writableLower.resize ( readableIndices.size () );
227- writableUpper.resize ( readableIndices.size () );
198+ std::vector<T> lowerSegments ( segments.begin (), segments.begin () + midOffset );
199+ std::vector<T> upperSegments ( segments.begin () + midOffset, segments.end () );
228200
229- for ( size_t i = 0 ; i < readableIndices.size (); ++i )
230- {
231- size_t index = readableIndices[i];
232- writableLower[i] = lowerSegmentsSet.find ( readable[index] ) == lowerSegmentsSet.end ();
233- writableUpper[i] = upperSegmentsSet.find ( readable[index] ) == upperSegmentsSet.end ();
234-
235- deleteCount += ( writableLower[i] && !lowerSegments.empty () ) || ( writableUpper[i] && !upperSegments.empty () ) ? 1 : 0 ;
236- }
237- }
238- else
239- {
240- writableLower.resize ( readable.size () );
241- writableUpper.resize ( readable.size () );
242-
243- for ( size_t i = 0 ; i < readable.size (); ++i )
244- {
245- writableLower[i] = lowerSegmentsSet.find ( readable[i] ) == lowerSegmentsSet.end ();
246- writableUpper[i] = upperSegmentsSet.find ( readable[i] ) == upperSegmentsSet.end ();
247- deleteCount += ( writableLower[i] && !lowerSegments.empty () ) || ( writableUpper[i] && !upperSegments.empty () ) ? 1 : 0 ;
248- }
249- }
201+ std::set<T> lowerSegmentsSet ( lowerSegments.begin (), lowerSegments.end () );
202+ std::set<T> upperSegmentsSet ( upperSegments.begin (), upperSegments.end () );
250203
251- if ( m_segments.size () == 1 && deleteCount == 0 )
252- {
253- m_outputPrimitives[m_offset] = m_primitive;
254- return nullptr ;
255- }
204+ const auto &readable = IECore::runTimeCast<IECore::TypedData<std::vector<T> > >( segmentPrimVar.data )->readable ();
256205
257- IECoreScene::PrimitiveVariable::Interpolation i = splitPrimvarInterpolation ( m_primitive.get () );
206+ IECore::BoolVectorDataPtr deletionArrayLower = new IECore::BoolVectorData ();
207+ auto &writableLower = deletionArrayLower->writable ();
258208
259- IECoreScene::PrimitiveVariable delPrimVarLower ( i, deletionArrayLower );
260- Ptr a = m_splitter ( m_primitive. get (), delPrimVarLower, false , m_canceller ) ;
209+ IECore::BoolVectorDataPtr deletionArrayUpper = new IECore::BoolVectorData ( );
210+ auto &writableUpper = deletionArrayUpper-> writable () ;
261211
262- IECoreScene::PrimitiveVariable delPrimVarUpper ( i, deletionArrayUpper);
263- Ptr b = m_splitter ( m_primitive.get (), delPrimVarUpper, false , m_canceller ) ;
212+ size_t deleteCount = 0 ;
213+ if ( segmentPrimVar.indices )
214+ {
215+ auto &readableIndices = segmentPrimVar.indices ->readable ();
216+ writableLower.resize ( readableIndices.size () );
217+ writableUpper.resize ( readableIndices.size () );
264218
265- size_t numSplits = 2 ;
219+ for ( size_t i = 0 ; i < readableIndices.size (); ++i )
220+ {
221+ size_t index = readableIndices[i];
222+ writableLower[i] = lowerSegmentsSet.find ( readable[index] ) == lowerSegmentsSet.end ();
223+ writableUpper[i] = upperSegmentsSet.find ( readable[index] ) == upperSegmentsSet.end ();
266224
267- set_ref_count ( 1 + numSplits);
225+ deleteCount += ( writableLower[i] && !lowerSegments.empty () ) || ( writableUpper[i] && !upperSegments.empty () ) ? 1 : 0 ;
226+ }
227+ }
228+ else
229+ {
230+ writableLower.resize ( readable.size () );
231+ writableUpper.resize ( readable.size () );
268232
269- SplitTask *tA = new ( allocate_child () ) SplitTask ( lowerSegments, a, m_splitter, m_primvarName, m_outputPrimitives, m_offset, m_depth + 1 , m_canceller);
270- spawn ( *tA );
233+ for ( size_t i = 0 ; i < readable.size (); ++i )
234+ {
235+ writableLower[i] = lowerSegmentsSet.find ( readable[i] ) == lowerSegmentsSet.end ();
236+ writableUpper[i] = upperSegmentsSet.find ( readable[i] ) == upperSegmentsSet.end ();
237+ deleteCount += ( writableLower[i] && !lowerSegments.empty () ) || ( writableUpper[i] && !upperSegments.empty () ) ? 1 : 0 ;
238+ }
239+ }
271240
272- SplitTask *tB = new ( allocate_child () ) SplitTask ( upperSegments, b, m_splitter, m_primvarName, m_outputPrimitives, m_offset + offset, m_depth + 1 , m_canceller );
273- spawn ( *tB );
241+ if ( segments.size () == 1 && deleteCount == 0 )
242+ {
243+ outputPrimitives[offset] = primitive;
244+ return ;
245+ }
274246
275- wait_for_all ( );
247+ IECoreScene::PrimitiveVariable::Interpolation i = splitPrimvarInterpolation ( primitive. get () );
276248
277- return nullptr ;
278- }
249+ IECoreScene::PrimitiveVariable delPrimVarLower ( i, deletionArrayLower ) ;
250+ Ptr a = splitter ( primitive. get (), delPrimVarLower, false , canceller );
279251
280- private:
252+ IECoreScene::PrimitiveVariable delPrimVarUpper ( i, deletionArrayUpper);
253+ Ptr b = splitter ( primitive.get (), delPrimVarUpper, false , canceller );
281254
282- std::vector<T> m_segments;
283- typename P::Ptr m_primitive;
284- const S &m_splitter;
285- std::string m_primvarName;
286- std::vector<Ptr> &m_outputPrimitives;
287- size_t m_offset;
288- size_t m_depth;
289- const IECore::Canceller *m_canceller;
290- };
255+ tbb::parallel_for (
256+ tbb::blocked_range<size_t >( 0 , 2 ),
257+ [&]( const tbb::blocked_range<size_t > &r )
258+ {
259+ for ( size_t i = r.begin (); i != r.end (); ++i )
260+ {
261+ if ( i == 0 )
262+ {
263+ splitPrimitive<T, S, P>( lowerSegments, a, splitter, primvarName, outputPrimitives, offset, depth + 1 , canceller, taskGroupContext );
264+ }
265+ else
266+ {
267+ splitPrimitive<T, S, P>( upperSegments, b, splitter, primvarName, outputPrimitives, offset + midOffset, depth + 1 , canceller, taskGroupContext );
268+ }
269+ }
270+ },
271+ taskGroupContext
272+ );
273+ }
291274
292275template <typename P, typename S>
293276class TaskSegmenter
@@ -323,17 +306,17 @@ class TaskSegmenter
323306 ReturnType results ( segmentsReadable.size () );
324307
325308 tbb::task_group_context taskGroupContext ( tbb::task_group_context::isolated );
326- SplitTask<T, S, P> *task = new ( tbb::task::allocate_root ( taskGroupContext ) ) SplitTask <T, S, P>(
309+ splitPrimitive <T, S, P>(
327310 segmentsReadable,
328311 const_cast <P *>(m_primitive),
329312 m_splitter,
330313 m_primVarName,
331314 results,
332315 0 ,
333316 0 ,
334- m_canceller
317+ m_canceller,
318+ taskGroupContext
335319 );
336- tbb::task::spawn_root_and_wait ( *task );
337320
338321 return results;
339322
0 commit comments