ObjectPtr FromHoudiniPolygonsConverter::doDetailConversion( const GU_Detail *geo, const CompoundObject *operands ) const { const GA_PrimitiveList &primitives = geo->getPrimitiveList(); MeshPrimitivePtr result = new MeshPrimitive(); size_t numEdges = 0; std::vector<int> vertIds; std::vector<int> vertsPerFace; GA_Offset start, end; for( GA_Iterator it( geo->getPrimitiveRange() ); it.blockAdvance( start, end ); ) { for( GA_Offset offset = start; offset < end; ++offset ) { const GA_Primitive *prim = primitives.get( offset ); if( prim->getTypeId() != GEO_PRIMPOLY ) { throw std::runtime_error( "FromHoudiniPolygonsConverter: Geometry contains non-polygon primitives" ); } size_t numPrimVerts = prim->getVertexCount(); vertsPerFace.push_back( numPrimVerts ); numEdges += numPrimVerts; std::vector<int> ids( numPrimVerts ); for( size_t j = 0; j < numPrimVerts; j++ ) { vertIds.push_back( geo->pointIndex( prim->getPointOffset( numPrimVerts - 1 - j ) ) ); } } } result->setTopology( new IntVectorData( vertsPerFace ), new IntVectorData( vertIds ) ); CompoundObjectPtr modifiedOperands = transferMeshInterpolation( geo, operands, result.get() ); if( geo->getNumVertices() ) { transferAttribs( geo, result.get(), modifiedOperands ? modifiedOperands.get() : operands ); } // check for corners and creases, which would have been extracted via transferAttribs() // as they are no different to standard attribs in Houdini. convertCorners( result.get() ); convertCreases( result.get(), vertIds, numEdges ); return result; }
PrimitivePtr FromHoudiniPolygonsConverter::doPrimitiveConversion( const GU_Detail *geo, const CompoundObject *operands ) const { const GA_PrimitiveList &primitives = geo->getPrimitiveList(); MeshPrimitivePtr result = new MeshPrimitive(); GA_Iterator firstPrim = geo->getPrimitiveRange().begin(); for ( GA_Iterator it=firstPrim; !it.atEnd(); ++it ) { const GA_Primitive *prim = primitives.get( it.getOffset() ); if ( prim->getTypeId() != GEO_PRIMPOLY ) { throw std::runtime_error( "FromHoudiniPolygonsConverter: Geometry contains non-polygon primitives" ); } } // loop over primitives gathering mesh data std::vector<int> vertIds; std::vector<int> vertsPerFace; for ( GA_Iterator it=firstPrim; !it.atEnd(); ++it ) { const GA_Primitive *prim = primitives.get( it.getOffset() ); size_t numPrimVerts = prim->getVertexCount(); vertsPerFace.push_back( numPrimVerts ); std::vector<int> ids( numPrimVerts ); for ( size_t j=0; j < numPrimVerts; j++ ) { vertIds.push_back( geo->pointIndex( prim->getPointOffset( numPrimVerts - 1 - j ) ) ); } } result->setTopology( new IntVectorData( vertsPerFace ), new IntVectorData( vertIds ) ); if ( geo->getNumVertices() ) { transferAttribs( geo, result, operands ); } return result; }
ObjectPtr BINMeshReader::doOperation( const CompoundObject *operands ) { const std::string &fileName = m_fileNameParameter->getTypedValue(); ifstream f( fileName.c_str() ); f.seekg( 0, ios_base::beg ); uint32_t magic = 0; readLittleEndian( f, magic ); uint32_t version = 0; readLittleEndian( f, version ); if ( version <= 3 ) { throw IOException(( boost::format( "BINMeshReader: '%s' is of an unsupported version" ) % fileName ).str() ); } MeshPrimitivePtr mesh = new MeshPrimitive(); uint32_t numVertices = 0; bool foundGeometryChunk = false; bool done = false; uint32_t chunkId = 0; while ( !done && !f.fail() ) { readLittleEndian( f, chunkId ); if ( f.fail() ) { throw IOException(( boost::format( "BINMeshReader: Error encountered while reading '%s'" ) % fileName ).str() ); } if ( chunkId == 0xDEDEDEDE ) /// EOF marker { if ( !foundGeometryChunk ) { throw IOException(( boost::format( "BINMeshReader: No geometry chunk encountered while reading '%s'" ) % fileName ).str() ); } done = true; } else if ( chunkId == 0xCCCCCCCC ) /// geometry chunk { if ( foundGeometryChunk ) { throw IOException(( boost::format( "BINMeshReader: Duplicate geometry chunk encountered while reading '%s'" ) % fileName ).str() ); } foundGeometryChunk = true; V3fVectorDataPtr pData = new V3fVectorData(); readLittleEndian( f, numVertices ); pData->writable().resize( numVertices ); for ( uint32_t i = 0; i < numVertices; i ++ ) { V3f p; readLittleEndian( f, p.x ); readLittleEndian( f, p.y ); readLittleEndian( f, p.z ); pData->writable()[i] = p; } uint32_t numFaces = 0; readLittleEndian( f, numFaces ); IntVectorDataPtr vertsPerFaceData = new IntVectorData(); /// All faces are triangles vertsPerFaceData->writable().resize( numFaces, 3 ); IntVectorDataPtr vertIdsData = new IntVectorData(); vertIdsData->writable().reserve( numFaces * 3 ); for ( uint32_t i = 0; i < numFaces; i ++ ) { uint32_t v0 = 0, v1 = 0, v2 = 0; readLittleEndian( f, v0 ); readLittleEndian( f, v1 ); readLittleEndian( f, v2 ); vertIdsData->writable().push_back( v0 ); vertIdsData->writable().push_back( v1 ); vertIdsData->writable().push_back( v2 ); } mesh->variables[ "P" ] = PrimitiveVariable( PrimitiveVariable::Vertex, pData ); mesh->setTopology( vertsPerFaceData, vertIdsData, "linear" ); } else if ( chunkId == 0xCCCCCC00 ) /// texture chunk { if ( !foundGeometryChunk ) { throw IOException(( boost::format( "BINMeshReader: No geometry chunk encountered while reading '%s'" ) % fileName ).str() ); } uint32_t numFluids = 0; readLittleEndian( f, numFluids ); V3fVectorDataPtr uvwData = new V3fVectorData(); uvwData->writable().resize( numVertices ); for ( uint32_t v = 0; v < numVertices; v ++ ) { for ( uint32_t fl = 0; fl < numFluids - 1; fl ++ ) { /// Just skip over there for now /// \todo Work out what to do with them float textureWeight = 0.0f; readLittleEndian( f, textureWeight ); } V3f uvw; readLittleEndian( f, uvw.x ); readLittleEndian( f, uvw.y ); readLittleEndian( f, uvw.z ); uvwData->writable()[v] = uvw; } mesh->variables[ "uvw" ] = PrimitiveVariable( PrimitiveVariable::Vertex, uvwData ); } else if ( chunkId == 0xCCCCCC11 ) /// velocity chunk { if ( !foundGeometryChunk ) { throw IOException(( boost::format( "BINMeshReader: No geometry chunk encountered while reading '%s'" ) % fileName ).str() ); } V3fVectorDataPtr velocityData = new V3fVectorData(); velocityData->writable().resize( numVertices ); for ( uint32_t i = 0; i < numVertices; i ++ ) { V3f vel; readLittleEndian( f, vel.x ); readLittleEndian( f, vel.y ); readLittleEndian( f, vel.z ); velocityData->writable()[i] = vel; } mesh->variables[ "velocity" ] = PrimitiveVariable( PrimitiveVariable::Vertex, velocityData ); } else { throw IOException(( boost::format( "BINMeshReader: Invalid chunk encountered while reading '%s'" ) % fileName ).str() ); } } if ( chunkId != 0xDEDEDEDE ) { throw IOException(( boost::format( "BINMeshReader: No end of file chunk encountered while reading '%s'" ) % fileName ).str() ); } assert( mesh ); return mesh; }