void CurveTangentsOp::modifyTypedPrimitive( CurvesPrimitive *curves, const CompoundObject *operands ) { if( !curves->arePrimitiveVariablesValid( ) ) { throw InvalidArgumentException( "CurveTangentsOp : CurvesPrimitive variables are invalid." ); } // The CurvesPrimitiveEvaluator currently only supports "P". Data * pData = curves->variableData<Data>( "P", PrimitiveVariable::Vertex ); if( !pData ) { throw InvalidArgumentException( "CurveTangentsOp : CurvesPrimitive has no Vertex \"P\" primitive variable." ); } const IntVectorData *vertsPerCurve = curves->verticesPerCurve(); DataCastOpPtr dco = new DataCastOp(); dco->targetTypeParameter()->setNumericValue( FloatVectorDataTypeId ); CurvesPrimitiveEvaluatorPtr evaluator = new CurvesPrimitiveEvaluator( curves ); CalculateTangents f( vertsPerCurve->readable(), evaluator ); despatchTypedData<CalculateTangents, TypeTraits::IsVec3VectorTypedData, HandleErrors>( pData, f ); curves->variables[ vTangentPrimVarNameParameter()->getTypedValue() ] = PrimitiveVariable( PrimitiveVariable::Vertex, f.vTangentsData ); assert( curves->arePrimitiveVariablesValid() ); }
PointsPrimitivePtr mergePoints( const std::vector<const PointsPrimitive *> &pointsPrimitives ) { size_t totalPointCount = 0; typedef std::map<std::string, IECore::TypeId> FoundPrimvars; FoundPrimvars foundPrimvars; PrimitiveVariableMap constantPrimVars; std::vector<PointsPrimitivePtr> validatedPointsPrimitives( pointsPrimitives.size() ); // find out which primvars can be merged for( size_t i = 0; i < pointsPrimitives.size(); ++i ) { PointsPrimitivePtr pointsPrimitive = validatedPointsPrimitives[i] = pointsPrimitives[i]->copy(); totalPointCount += pointsPrimitive->getNumPoints(); PrimitiveVariableMap &variables = pointsPrimitive->variables; for( PrimitiveVariableMap::iterator it = variables.begin(); it != variables.end(); ++it ) { DataPtr data = it->second.data; const IECore::TypeId typeId = data->typeId(); PrimitiveVariable::Interpolation interpolation = it->second.interpolation; const std::string &name = it->first; bool bExistingConstant = constantPrimVars.find( name ) != constantPrimVars.end(); FoundPrimvars::const_iterator fIt = foundPrimvars.find( name ); bool bExistingVertex = fIt != foundPrimvars.end(); if( interpolation == PrimitiveVariable::Constant ) { if( bExistingVertex ) { std::string msg = boost::str( boost::format( "PointsAlgo::mergePoints mismatching primvar %s" ) % name ); throw InvalidArgumentException( msg ); } if( !bExistingConstant ) { constantPrimVars[name] = it->second; } continue; } if( interpolation == PrimitiveVariable::Vertex ) { PrimitiveVariableMap::const_iterator constantPrimVarIt = constantPrimVars.find( name ); if( constantPrimVarIt != constantPrimVars.end() ) { std::string msg = boost::str( boost::format( "PointsAlgo::mergePoints mismatching primvar %s" ) % name ); throw InvalidArgumentException( msg ); } if( !bExistingVertex ) { foundPrimvars[name] = typeId; } else { if( fIt->second != typeId ) { DataCastOpPtr castOp = new DataCastOp(); castOp->objectParameter()->setValue( data ); castOp->targetTypeParameter()->setNumericValue( fIt->second ); try { it->second.data = runTimeCast<Data>( castOp->operate() ); } catch( const IECore::Exception &e ) { std::string msg = boost::str( boost::format( "PointsAlgo::mergePoints unable to cast primvar %s (%s) " ) % name % e.what() ); throw InvalidArgumentException( msg ); } } } } } } // allocate the new points primitive and copy the primvars PointsPrimitivePtr newPoints = new PointsPrimitive( totalPointCount ); // copy constant primvars for( PrimitiveVariableMap::const_iterator it = constantPrimVars.begin(); it != constantPrimVars.end(); ++it ) { newPoints->variables[it->first] = it->second; } // merge vertex primvars for( FoundPrimvars::const_iterator it = foundPrimvars.begin(); it != foundPrimvars.end(); ++it ) { DataPtr mergedData = mergePrimVars( validatedPointsPrimitives, it->first, totalPointCount ); newPoints->variables[it->first] = PrimitiveVariable( PrimitiveVariable::Vertex, mergedData ); } return newPoints; }
void MeshTangentsOp::modifyTypedPrimitive( MeshPrimitive * mesh, const CompoundObject * operands ) { if( !mesh->arePrimitiveVariablesValid( ) ) { throw InvalidArgumentException( "MeshTangentsOp : MeshPrimitive variables are invalid." ); } const std::string &pPrimVarName = pPrimVarNameParameter()->getTypedValue(); Data * pData = mesh->variableData<Data>( pPrimVarName, PrimitiveVariable::Vertex ); if( !pData ) { string e = boost::str( boost::format( "MeshTangentsOp : MeshPrimitive has no Vertex \"%s\" primitive variable." ) % pPrimVarName ); throw InvalidArgumentException( e ); } const IntVectorData * vertsPerFace = mesh->verticesPerFace(); for ( IntVectorData::ValueType::const_iterator it = vertsPerFace->readable().begin(); it != vertsPerFace->readable().end(); ++it ) { if ( *it != 3 ) { throw InvalidArgumentException( "MeshTangentsOp : MeshPrimitive has non-triangular faces." ); } } const std::string &uPrimVarName = uPrimVarNameParameter()->getTypedValue(); const std::string &vPrimVarName = vPrimVarNameParameter()->getTypedValue(); const std::string &uvIndicesPrimVarName = uvIndicesPrimVarNameParameter()->getTypedValue(); FloatVectorDataPtr uData = mesh->variableData<FloatVectorData>( uPrimVarName, PrimitiveVariable::FaceVarying ); if( !uData ) { throw InvalidArgumentException( ( boost::format( "MeshTangentsOp : MeshPrimitive has no FaceVarying FloatVectorData primitive variable named \"%s\"." ) % ( uPrimVarName ) ).str() ); } FloatVectorDataPtr vData = mesh->variableData<FloatVectorData>( vPrimVarName, PrimitiveVariable::FaceVarying ); if( !vData ) { throw InvalidArgumentException( ( boost::format( "MeshTangentsOp : MeshPrimitive has no FaceVarying FloatVectorData primitive variable named \"%s\"." ) % ( vPrimVarName ) ).str() ); } ConstIntVectorDataPtr uvIndicesData = 0; if( uvIndicesPrimVarName=="" ) { uvIndicesData = mesh->vertexIds(); } else { uvIndicesData = mesh->variableData<IntVectorData>( uvIndicesPrimVarName, PrimitiveVariable::FaceVarying ); if( !uvIndicesData ) { throw InvalidArgumentException( ( boost::format( "MeshTangentsOp : MeshPrimitive has no FaceVarying IntVectorData primitive variable named \"%s\"." ) % ( uvIndicesPrimVarName ) ).str() ); } } DataCastOpPtr dco = new DataCastOp(); dco->targetTypeParameter()->setNumericValue( FloatVectorDataTypeId ); bool orthoTangents = orthogonalizeTangentsParameter()->getTypedValue(); CalculateTangents f( vertsPerFace->readable(), mesh->vertexIds()->readable(), uData->readable(), vData->readable(), uvIndicesData->readable(), orthoTangents ); despatchTypedData<CalculateTangents, TypeTraits::IsFloatVec3VectorTypedData, HandleErrors>( pData, f ); mesh->variables[ uTangentPrimVarNameParameter()->getTypedValue() ] = PrimitiveVariable( PrimitiveVariable::FaceVarying, f.fvUTangentsData ); mesh->variables[ vTangentPrimVarNameParameter()->getTypedValue() ] = PrimitiveVariable( PrimitiveVariable::FaceVarying, f.fvVTangentsData ); assert( mesh->arePrimitiveVariablesValid() ); }