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; }