| 814 | |
| 815 | |
| 816 | MeshPrimitivePtr IECoreScene::MeshAlgo::MeshSplitter::mesh( int segmentId, const IECore::Canceller *canceller ) const |
| 817 | { |
| 818 | if( segmentId < 0 || segmentId > (int)m_meshIndices.size() ) |
| 819 | { |
| 820 | throw IECore::Exception( "Invalid segment id " + std::to_string( segmentId ) ); |
| 821 | } |
| 822 | |
| 823 | // Based on our index, and the index of the next mesh in m_meshIndices, we know how many faces to output |
| 824 | const int startIndex = m_meshIndices[ segmentId ]; |
| 825 | const int endIndex = ( segmentId + 1 < (int)m_meshIndices.size() ) ? m_meshIndices[ segmentId + 1 ] : m_faceRemap.size(); |
| 826 | const int numFaces = endIndex - startIndex; |
| 827 | |
| 828 | IntVectorDataPtr verticesPerFaceData = new IntVectorData(); |
| 829 | std::vector<int> &verticesPerFace = verticesPerFaceData->writable(); |
| 830 | verticesPerFace.reserve( numFaces ); |
| 831 | int totalFaceVerts = 0; |
| 832 | const std::vector<int> &sourceVertexIds = m_mesh->vertexIds()->readable(); |
| 833 | const std::vector<int> &sourceVerticesPerFace = m_mesh->verticesPerFace()->readable(); |
| 834 | |
| 835 | Canceller::check( canceller ); |
| 836 | // Outputting the verticesPerFace is straightforward - just read the source mesh's verticesPerFace |
| 837 | // through m_faceRemap |
| 838 | for( int i = startIndex; i < endIndex; i++ ) |
| 839 | { |
| 840 | int originalFaceIndex = m_faceRemap[i]; |
| 841 | int faceVerts = sourceVerticesPerFace[ originalFaceIndex ]; |
| 842 | verticesPerFace.push_back( faceVerts ); |
| 843 | totalFaceVerts += faceVerts; |
| 844 | } |
| 845 | |
| 846 | // For the vertexIds, we need to iterate through all the original faces that are referenced in m_faceRemap, |
| 847 | // and we need to use them to build a Reindexer that only references the vertices we are actually using |
| 848 | Canceller::check( canceller ); |
| 849 | Reindexer vertReindexer( m_mesh->variableSize( PrimitiveVariable::Interpolation::Vertex ), totalFaceVerts ); |
| 850 | for( int i = startIndex; i < endIndex; i++ ) |
| 851 | { |
| 852 | if( i % 1000 == 0 ) |
| 853 | { |
| 854 | Canceller::check( canceller ); |
| 855 | } |
| 856 | |
| 857 | int originalFaceIndex = m_faceRemap[i]; |
| 858 | int faceVerts = sourceVerticesPerFace[ originalFaceIndex ]; |
| 859 | int faceStart = m_faceIndices[ originalFaceIndex ]; |
| 860 | for( int j = 0; j < faceVerts; j++ ) |
| 861 | { |
| 862 | vertReindexer.addIndex( sourceVertexIds[ faceStart + j ] ); |
| 863 | } |
| 864 | } |
| 865 | |
| 866 | // We need to track which original vertex our vertices came from so we can pull primvar data from them. |
| 867 | Canceller::check( canceller ); |
| 868 | std::vector<int> vertRemapBackwards; |
| 869 | vertReindexer.getDataRemapping( vertRemapBackwards ); |
| 870 | |
| 871 | MeshPrimitivePtr ret = new MeshPrimitive( verticesPerFaceData, vertReindexer.getNewIndices(), m_mesh->interpolation() ); |
| 872 | |
| 873 | // In order to remap the corners, we test every vertex in the original corner list, and see if it is |