| 334 | } // namespace |
| 335 | |
| 336 | IECoreScene::MeshAlgo::MeshSplitter::MeshSplitter( ConstMeshPrimitivePtr mesh, const PrimitiveVariable &segmentPrimitiveVariable, const IECore::Canceller *canceller ) : m_mesh( mesh ), m_segmentPrimitiveVariable( segmentPrimitiveVariable ) |
| 337 | { |
| 338 | if( segmentPrimitiveVariable.interpolation != IECoreScene::PrimitiveVariable::Interpolation::Uniform ) |
| 339 | { |
| 340 | throw IECore::Exception( "Primitive variable passed to MeshSplitter must be uniform." ); |
| 341 | } |
| 342 | |
| 343 | if( !mesh->isPrimitiveVariableValid( segmentPrimitiveVariable ) ) |
| 344 | { |
| 345 | throw IECore::Exception( "Primitive variable passed to MeshSplitter must be valid." ); |
| 346 | } |
| 347 | |
| 348 | const size_t numFaces = mesh->numFaces(); |
| 349 | if( numFaces == 0 ) |
| 350 | { |
| 351 | // If we don't initialize anything, numMeshes() will return 0, meaning there is no valid context to |
| 352 | // call mesh() in, which is correct for an empty mesh |
| 353 | return; |
| 354 | } |
| 355 | |
| 356 | int numSegments = 0; |
| 357 | ConstIntVectorDataPtr faceToSegmentIndexData; |
| 358 | std::vector<int> remapSegmentIndices; |
| 359 | // remapSegmentIndexMin specifies the lowest value in the faceToSegmentIndexBuffer that we need to remap: |
| 360 | // it shifts all accesses to the remapSegmentIndices, allowing remapSegmentIndices to be used when the |
| 361 | // lowest element is not 0 |
| 362 | int remapSegmentIndexMin = 0; |
| 363 | |
| 364 | |
| 365 | IECore::dispatch( segmentPrimitiveVariable.data.get(), [ segmentPrimitiveVariable, &numSegments, &faceToSegmentIndexData, &remapSegmentIndices, &remapSegmentIndexMin, canceller]( const auto *primVarData ) |
| 366 | { |
| 367 | using DataType = typename std::remove_pointer_t< decltype( primVarData ) >; |
| 368 | if constexpr ( !TypeTraits::IsVectorTypedData<DataType>::value ) |
| 369 | { |
| 370 | throw IECore::Exception( "Invalid PrimitiveVariable, data is not a vector." ); |
| 371 | } |
| 372 | else |
| 373 | { |
| 374 | initializeFaceToSegments< typename DataType::ValueType::value_type >( |
| 375 | primVarData, |
| 376 | segmentPrimitiveVariable.indices.get(), |
| 377 | numSegments, |
| 378 | faceToSegmentIndexData, |
| 379 | remapSegmentIndices, |
| 380 | remapSegmentIndexMin, |
| 381 | canceller |
| 382 | ); |
| 383 | } |
| 384 | } |
| 385 | ); |
| 386 | |
| 387 | const std::vector<int> &faceToSegmentIndex = faceToSegmentIndexData->readable(); |
| 388 | |
| 389 | // Now that we have our faceToSegmentIndex and remapSegmentIndices vector, we can count the number of faces |
| 390 | // for each output mesh |
| 391 | std::vector<int> faceCounts; |
| 392 | faceCounts.resize( numSegments, 0 ); |
| 393 | |