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;
}
Beispiel #3
0
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;
}