예제 #1
0
bool ToHoudiniPolygonsConverter::doConversion( const VisibleRenderable *renderable, GU_Detail *geo ) const
{
	const MeshPrimitive *mesh = static_cast<const MeshPrimitive *>( renderable );
	if ( !mesh )
	{
		return false;
	}
	
	GA_Range newPoints = appendPoints( geo, mesh->variableSize( PrimitiveVariable::Vertex ) );
	if ( !newPoints.isValid() || newPoints.empty() )
	{
		return false;
	}
	
	GA_OffsetList pointOffsets;
	pointOffsets.reserve( newPoints.getEntries() );
	for ( GA_Iterator it=newPoints.begin(); !it.atEnd(); ++it )
	{
		pointOffsets.append( it.getOffset() );
	}
	
	const std::vector<int> &vertexIds = mesh->vertexIds()->readable();
	const std::vector<int> &verticesPerFace = mesh->verticesPerFace()->readable();
	
	GA_OffsetList offsets;
	offsets.reserve( verticesPerFace.size() );
	
	size_t vertCount = 0;
	size_t numPrims = geo->getNumPrimitives();
	for ( size_t f=0; f < verticesPerFace.size(); f++ )
	{
		GU_PrimPoly *poly = GU_PrimPoly::build( geo, 0, GU_POLY_CLOSED, 0 );
		offsets.append( geo->primitiveOffset( numPrims + f ) );
		
		for ( size_t v=0; v < (size_t)verticesPerFace[f]; v++ )
		{
			poly->appendVertex( pointOffsets.get( vertexIds[ vertCount + verticesPerFace[f] - 1 - v ] ) );
		}
		
		vertCount += verticesPerFace[f];
	}
	
	GA_Range newPrims( geo->getPrimitiveMap(), offsets );
	transferAttribs( geo, newPoints, newPrims );
	
	// add the interpolation type
	if ( newPrims.isValid() )
	{
		std::string interpolation = ( mesh->interpolation() == "catmullClark" ) ? "subdiv" : "poly";
		StringVectorDataPtr interpolationVectorData = new StringVectorData();
		interpolationVectorData->writable().push_back( interpolation );
		std::vector<int> indexValues( newPrims.getEntries(), 0 );
		IntVectorDataPtr indexData = new IntVectorData( indexValues );
		ToHoudiniStringVectorAttribConverterPtr converter = new ToHoudiniStringVectorAttribConverter( interpolationVectorData );
		converter->indicesParameter()->setValidatedValue( indexData );
		converter->convert( "ieMeshInterpolation", geo, newPrims );
	}
	
	return true;
}
bool ToHoudiniPolygonsConverter::doConversion( const VisibleRenderable *renderable, GU_Detail *geo ) const
{
	const MeshPrimitive *mesh = static_cast<const MeshPrimitive *>( renderable );
	if ( !mesh )
	{
		return false;
	}
	
	GA_Range newPoints = appendPoints( geo, mesh->variableSize( PrimitiveVariable::Vertex ) );
	if ( !newPoints.isValid() || newPoints.empty() )
	{
		return false;
	}
	
	GA_OffsetList pointOffsets;
	pointOffsets.reserve( newPoints.getEntries() );
	for ( GA_Iterator it=newPoints.begin(); !it.atEnd(); ++it )
	{
		pointOffsets.append( it.getOffset() );
	}
	
	const std::vector<int> &vertexIds = mesh->vertexIds()->readable();
	const std::vector<int> &verticesPerFace = mesh->verticesPerFace()->readable();
	
	GA_OffsetList offsets;
	offsets.reserve( verticesPerFace.size() );
	
	size_t vertCount = 0;
	size_t numPrims = geo->getNumPrimitives();
	for ( size_t f=0; f < verticesPerFace.size(); f++ )
	{
		GU_PrimPoly *poly = GU_PrimPoly::build( geo, 0, GU_POLY_CLOSED, 0 );
		offsets.append( geo->primitiveOffset( numPrims + f ) );
		
		for ( size_t v=0; v < (size_t)verticesPerFace[f]; v++ )
		{
			poly->appendVertex( pointOffsets.get( vertexIds[ vertCount + verticesPerFace[f] - 1 - v ] ) );
		}
		
		vertCount += verticesPerFace[f];
	}
	
	GA_Range newPrims( geo->getPrimitiveMap(), offsets );
	transferAttribs( geo, newPoints, newPrims );
	
	return true;
}
GA_Range ToHoudiniGeometryConverter::appendPoints( GA_Detail *geo, size_t numPoints ) const
{
	if ( !numPoints )
	{
		return GA_Range();
	}
	
	GA_OffsetList offsets;
	offsets.reserve( numPoints );
	
	for ( size_t i=0; i < numPoints; ++i )
	{
		offsets.append( geo->appendPoint() );
	}
	
	return GA_Range( geo->getPointMap(), offsets );
}
GA_Range ToHoudiniGeometryConverter::appendPoints( GA_Detail *geo, size_t numPoints ) const
{
	if ( !numPoints )
	{
		return GA_Range();
	}
	
	GA_OffsetList offsets;
	offsets.reserve( numPoints );
	
	/// \todo: try GA_Detail::appendPointBlock instead. SideFx says it is much faster
	for ( size_t i=0; i < numPoints; ++i )
	{
		offsets.append( geo->appendPoint() );
	}
	
	return GA_Range( geo->getPointMap(), offsets );
}
bool ToHoudiniCurvesConverter::doConversion( const VisibleRenderable *renderable, GU_Detail *geo ) const
{
	const CurvesPrimitive *curves = static_cast<const CurvesPrimitive *>( renderable );
	if ( !curves )
	{
		return false;
	}
	
	bool periodic = curves->periodic();
	bool duplicatedEnds = !periodic && ( curves->basis() == CubicBasisf::bSpline() );
	
	size_t numPoints = curves->variableSize( PrimitiveVariable::Vertex );
	if ( duplicatedEnds )
	{
		numPoints -= 4 * curves->numCurves();
	}
	
	GA_Range newPoints = appendPoints( geo, numPoints );
	if ( !newPoints.isValid() || newPoints.empty() )
	{
		return false;
	}
	
	GA_OffsetList pointOffsets;
	pointOffsets.reserve( newPoints.getEntries() );
	for ( GA_Iterator it=newPoints.begin(); !it.atEnd(); ++it )
	{
		pointOffsets.append( it.getOffset() );
	}
	
	const std::vector<int> &verticesPerCurve = curves->verticesPerCurve()->readable();
	int order = ( curves->basis() == CubicBasisf::bSpline() ) ? 4 : 2;
	bool interpEnds = !(periodic && ( curves->basis() == CubicBasisf::bSpline() ));
	
	GA_OffsetList offsets;
	offsets.reserve( verticesPerCurve.size() );
	
	size_t vertCount = 0;
	size_t numPrims = geo->getNumPrimitives();
	for ( size_t c=0; c < verticesPerCurve.size(); c++ )
	{
		size_t numVerts = duplicatedEnds ? verticesPerCurve[c] - 4 : verticesPerCurve[c];
		GU_PrimNURBCurve *curve = GU_PrimNURBCurve::build( geo, numVerts, order, periodic, interpEnds, false );
		if ( !curve )
		{
			return false;
		}
		
		offsets.append( geo->primitiveOffset( numPrims + c ) );
		
		for ( size_t v=0; v < numVerts; v++ )
		{
			curve->setVertexPoint( v, pointOffsets.get( vertCount + v ) );
		}
		
		vertCount += numVerts;
	}
	
	GA_Range newPrims( geo->getPrimitiveMap(), offsets );
	transferAttribs( geo, newPoints, newPrims );
	
	return true;
}