void getConnectedChildPlugs(const char *attrName, MFnDependencyNode& depFn, bool dest, MPlugArray& thisNodePlugs, MPlugArray& otherSidePlugs) { MPlug p = depFn.findPlug(attrName); if (p.isCompound() && !p.isArray()) { getConnectedChildPlugs(p, dest, thisNodePlugs, otherSidePlugs); return; } if (p.isArray()) { for (uint i = 0; i < p.numElements(); i++) { if (p[i].numConnectedChildren() == 0) continue; if (!p[i].isCompound()) getConnectedChildPlugs(p[i], dest, thisNodePlugs, otherSidePlugs); else { if (getAttributeNameFromPlug(p) == MString("colorEntryList")) { getConnectedChildPlugs(p[i].child(1), dest, thisNodePlugs, otherSidePlugs); } } } } }
//--------------------------------------------------- bool DagHelper::connectToList ( const MPlug& source, const MObject& destination, const MString& destinationAttribute, int* _index ) { MStatus status; MFnDependencyNode destFn ( destination ); MPlug dest = destFn.findPlug ( destinationAttribute, &status ); if ( status != MStatus::kSuccess ) return false; if ( !dest.isArray() ) return false; int index = ( _index != NULL ) ? *_index : -1; if ( index < 0 ) { index = getNextAvailableIndex ( dest, ( int ) dest.evaluateNumElements() ); if ( _index != NULL ) *_index = index; } MPlug d = dest.elementByLogicalIndex ( index ); MDGModifier modifier; modifier.connect ( source, d ); status = modifier.doIt(); return status == MStatus::kSuccess; }
// -------------------------------------------------------------------------------------------- void polyModifierCmd::collectNodeState() // -------------------------------------------------------------------------------------------- { MStatus status; // Collect node state information on the given polyMeshShape // // - HasHistory (Construction History exists) // - HasTweaks // - HasRecordHistory (Construction History is turned on) // fDagPath.extendToShape(); MObject meshNodeShape = fDagPath.node(); MFnDependencyNode depNodeFn; depNodeFn.setObject( meshNodeShape ); MPlug inMeshPlug = depNodeFn.findPlug( "inMesh" ); fHasHistory = inMeshPlug.isConnected(); // Tweaks exist only if the multi "pnts" attribute contains plugs // which contain non-zero tweak values. Use false, until proven true // search algorithm. // fHasTweaks = false; MPlug tweakPlug = depNodeFn.findPlug( "pnts" ); if( !tweakPlug.isNull() ) { // ASSERT: tweakPlug should be an array plug! // MAssert( (tweakPlug.isArray()), "tweakPlug.isArray() -- tweakPlug is not an array plug" ); MPlug tweak; MFloatVector tweakData; int i; int numElements = tweakPlug.numElements(); for( i = 0; i < numElements; i++ ) { tweak = tweakPlug.elementByPhysicalIndex( i, &status ); if( status == MS::kSuccess && !tweak.isNull() ) { getFloat3PlugValue( tweak, tweakData ); if( 0 != tweakData.x || 0 != tweakData.y || 0 != tweakData.z ) { fHasTweaks = true; break; } } } } int result; MGlobal::executeCommand( "constructionHistory -q -tgl", result ); fHasRecordHistory = (0 != result); }
// ------------------------------------------- MPlug AnimationHelper::getTargetedPlug ( MPlug parentPlug, int index ) { if ( index >= 0 && parentPlug.isCompound() ) { return parentPlug.child ( index ); } else if ( index >= 0 && parentPlug.isArray() ) { return parentPlug.elementByLogicalIndex ( index ); } else return parentPlug; }
void getDirectConnectedPlugs(const char *attrName, MFnDependencyNode& depFn, bool dest, MPlugArray& thisNodePlugs, MPlugArray& otherSidePlugs) { MPlug thisPlug = depFn.findPlug(attrName); if (!thisPlug.isArray()) { if (thisPlug.isConnected()) { thisNodePlugs.append(thisPlug); otherSidePlugs.append(getDirectConnectedPlug(thisPlug, dest)); } return; } for (uint i = 0; i < thisPlug.numElements(); i++) { if (thisPlug.isCompound()) { // we only support simple compounds like colorListEntry if (MString(attrName) == MString("colorEntryList")) { MPlug element = thisPlug[i]; if (element.child(0).isConnected()) { MPlug connectedPlug = element.child(0); thisNodePlugs.append(connectedPlug); otherSidePlugs.append(getDirectConnectedPlug(connectedPlug, dest)); } if (element.child(1).isConnected()) { MPlug connectedPlug = element.child(1); thisNodePlugs.append(connectedPlug); otherSidePlugs.append(getDirectConnectedPlug(connectedPlug, dest)); } } } else{ if (!thisPlug[i].isConnected()) { continue; } MPlug connectedPlug = thisPlug[i]; thisNodePlugs.append(connectedPlug); otherSidePlugs.append(getDirectConnectedPlug(connectedPlug, dest)); } } }
// -------------------------------------------------------------------------------------------- MStatus polyModifierCmd::undoTweakProcessing() // -------------------------------------------------------------------------------------------- { MStatus status = MS::kSuccess; if( fHasTweaks ) { MFnDependencyNode depNodeFn; MObject meshNodeShape; MPlug meshTweakPlug; MPlug tweak; MObject tweakData; meshNodeShape = fDagPath.node(); depNodeFn.setObject( meshNodeShape ); meshTweakPlug = depNodeFn.findPlug( "pnts" ); MStatusAssert( (meshTweakPlug.isArray()), "meshTweakPlug.isArray() -- meshTweakPlug is not an array plug" ); unsigned i; unsigned numElements = fTweakIndexArray.length(); for( i = 0; i < numElements; i++ ) { tweak = meshTweakPlug.elementByLogicalIndex( fTweakIndexArray[i] ); getFloat3asMObject( fTweakVectorArray[i], tweakData ); tweak.setValue( tweakData ); } // In the case of no history, the duplicate node shape will be disconnected on undo // so, there is no need to undo the tweak processing on it. // } return status; }
PXR_NAMESPACE_OPEN_SCOPE /* static */ bool PxrUsdMayaTranslatorMesh::Create( const UsdGeomMesh& mesh, MObject parentNode, const PxrUsdMayaPrimReaderArgs& args, PxrUsdMayaPrimReaderContext* context) { if (!mesh) { return false; } const UsdPrim& prim = mesh.GetPrim(); MStatus status; // Create node (transform) MObject mayaNodeTransformObj; if (!PxrUsdMayaTranslatorUtil::CreateTransformNode(prim, parentNode, args, context, &status, &mayaNodeTransformObj)) { return false; } VtArray<GfVec3f> points; VtArray<GfVec3f> normals; VtArray<int> faceVertexCounts; VtArray<int> faceVertexIndices; UsdAttribute fvc = mesh.GetFaceVertexCountsAttr(); if (fvc.ValueMightBeTimeVarying()){ // at some point, it would be great, instead of failing, to create a usd/hydra proxy node // for the mesh, perhaps? For now, better to give a more specific error MGlobal::displayError( TfStringPrintf("<%s> is a topologically varying Mesh (animated faceVertexCounts). Skipping...", prim.GetPath().GetText()).c_str()); return false; } else { // for any non-topo-varying mesh, sampling at zero will get us the right answer fvc.Get(&faceVertexCounts, 0); } UsdAttribute fvi = mesh.GetFaceVertexIndicesAttr(); if (fvi.ValueMightBeTimeVarying()){ // at some point, it would be great, instead of failing, to create a usd/hydra proxy node // for the mesh, perhaps? For now, better to give a more specific error MGlobal::displayError( TfStringPrintf("<%s> is a topologically varying Mesh (animated faceVertexIndices). Skipping...", prim.GetPath().GetText()).c_str()); return false; } else { // for any non-topo-varying mesh, sampling at zero will get us the right answer fvi.Get(&faceVertexIndices, 0); } // Sanity Checks. If the vertex arrays are empty, skip this mesh if (faceVertexCounts.size() == 0 || faceVertexIndices.size() == 0) { MGlobal::displayError( TfStringPrintf("FaceVertex arrays are empty [Count:%zu Indices:%zu] on Mesh <%s>. Skipping...", faceVertexCounts.size(), faceVertexIndices.size(), prim.GetPath().GetText()).c_str()); return false; // invalid mesh, so exit } // Gather points and normals // If args.GetReadAnimData() is TRUE, // pick the first avaiable sample or default UsdTimeCode pointsTimeSample=UsdTimeCode::EarliestTime(); UsdTimeCode normalsTimeSample=UsdTimeCode::EarliestTime(); std::vector<double> pointsTimeSamples; size_t pointsNumTimeSamples = 0; if (args.GetReadAnimData()) { PxrUsdMayaTranslatorUtil::GetTimeSamples(mesh.GetPointsAttr(), args, &pointsTimeSamples); pointsNumTimeSamples = pointsTimeSamples.size(); if (pointsNumTimeSamples>0) { pointsTimeSample = pointsTimeSamples[0]; } std::vector<double> normalsTimeSamples; PxrUsdMayaTranslatorUtil::GetTimeSamples(mesh.GetNormalsAttr(), args, &normalsTimeSamples); if (normalsTimeSamples.size()) { normalsTimeSample = normalsTimeSamples[0]; } } mesh.GetPointsAttr().Get(&points, pointsTimeSample); mesh.GetNormalsAttr().Get(&normals, normalsTimeSample); if (points.size() == 0) { MGlobal::displayError( TfStringPrintf("Points arrays is empty on Mesh <%s>. Skipping...", prim.GetPath().GetText()).c_str()); return false; // invalid mesh, so exit } // == Convert data size_t mayaNumVertices = points.size(); MPointArray mayaPoints(mayaNumVertices); for (size_t i=0; i < mayaNumVertices; i++) { mayaPoints.set( i, points[i][0], points[i][1], points[i][2] ); } MIntArray polygonCounts( faceVertexCounts.cdata(), faceVertexCounts.size() ); MIntArray polygonConnects( faceVertexIndices.cdata(), faceVertexIndices.size() ); // == Create Mesh Shape Node MFnMesh meshFn; MObject meshObj = meshFn.create(mayaPoints.length(), polygonCounts.length(), mayaPoints, polygonCounts, polygonConnects, mayaNodeTransformObj, &status ); if (status != MS::kSuccess) { return false; } // Since we are "decollapsing", we will create a xform and a shape node for each USD prim std::string usdPrimName(prim.GetName().GetText()); std::string shapeName(usdPrimName); shapeName += "Shape"; // Set mesh name and register meshFn.setName(MString(shapeName.c_str()), false, &status); if (context) { std::string usdPrimPath(prim.GetPath().GetText()); std::string shapePath(usdPrimPath); shapePath += "/"; shapePath += shapeName; context->RegisterNewMayaNode( shapePath, meshObj ); // used for undo/redo } // If a material is bound, create (or reuse if already present) and assign it // If no binding is present, assign the mesh to the default shader const TfToken& shadingMode = args.GetShadingMode(); PxrUsdMayaTranslatorMaterial::AssignMaterial(shadingMode, mesh, meshObj, context); // Mesh is a shape, so read Gprim properties PxrUsdMayaTranslatorGprim::Read(mesh, meshObj, context); // Set normals if supplied MIntArray normalsFaceIds; if (normals.size() == static_cast<size_t>(meshFn.numFaceVertices())) { for (size_t i=0; i < polygonCounts.length(); i++) { for (int j=0; j < polygonCounts[i]; j++) { normalsFaceIds.append(i); } } if (normalsFaceIds.length() == static_cast<size_t>(meshFn.numFaceVertices())) { MVectorArray mayaNormals(normals.size()); for (size_t i=0; i < normals.size(); i++) { mayaNormals.set( MVector(normals[i][0], normals[i][1], normals[i][2]), i); } if (meshFn.setFaceVertexNormals(mayaNormals, normalsFaceIds, polygonConnects) != MS::kSuccess) { } } } // Determine if PolyMesh or SubdivMesh TfToken subdScheme = PxrUsdMayaMeshUtil::setSubdivScheme(mesh, meshFn, args.GetDefaultMeshScheme()); // If we are dealing with polys, check if there are normals // If we are dealing with SubdivMesh, read additional attributes and SubdivMesh properties if (subdScheme == UsdGeomTokens->none) { if (normals.size() == static_cast<size_t>(meshFn.numFaceVertices())) { PxrUsdMayaMeshUtil::setEmitNormals(mesh, meshFn, UsdGeomTokens->none); } } else { PxrUsdMayaMeshUtil::setSubdivInterpBoundary(mesh, meshFn, UsdGeomTokens->edgeAndCorner); PxrUsdMayaMeshUtil::setSubdivFVLinearInterpolation(mesh, meshFn); _AssignSubDivTagsToMesh(mesh, meshObj, meshFn); } // Set Holes VtArray<int> holeIndices; mesh.GetHoleIndicesAttr().Get(&holeIndices); // not animatable if ( holeIndices.size() != 0 ) { MUintArray mayaHoleIndices; mayaHoleIndices.setLength( holeIndices.size() ); for (size_t i=0; i < holeIndices.size(); i++) { mayaHoleIndices[i] = holeIndices[i]; } if (meshFn.setInvisibleFaces(mayaHoleIndices) == MS::kFailure) { MGlobal::displayError(TfStringPrintf("Unable to set Invisible Faces on <%s>", meshFn.fullPathName().asChar()).c_str()); } } // GETTING PRIMVARS std::vector<UsdGeomPrimvar> primvars = mesh.GetPrimvars(); TF_FOR_ALL(iter, primvars) { const UsdGeomPrimvar& primvar = *iter; const TfToken& name = primvar.GetBaseName(); const SdfValueTypeName& typeName = primvar.GetTypeName(); // If the primvar is called either displayColor or displayOpacity check // if it was really authored from the user. It may not have been // authored by the user, for example if it was generated by shader // values and not an authored colorset/entity. // If it was not really authored, we skip the primvar. if (name == PxrUsdMayaMeshColorSetTokens->DisplayColorColorSetName || name == PxrUsdMayaMeshColorSetTokens->DisplayOpacityColorSetName) { if (!PxrUsdMayaRoundTripUtil::IsAttributeUserAuthored(primvar)) { continue; } } // XXX: Maya stores UVs in MFloatArrays and color set data in MColors // which store floats, so we currently only import primvars holding // float-typed arrays. Should we still consider other precisions // (double, half, ...) and/or numeric types (int)? if (typeName == SdfValueTypeNames->Float2Array) { // We assume that Float2Array primvars are UV sets. if (!_AssignUVSetPrimvarToMesh(primvar, meshFn)) { MGlobal::displayWarning( TfStringPrintf("Unable to retrieve and assign data for UV set <%s> on mesh <%s>", name.GetText(), mesh.GetPrim().GetPath().GetText()).c_str()); } } else if (typeName == SdfValueTypeNames->FloatArray || typeName == SdfValueTypeNames->Float3Array || typeName == SdfValueTypeNames->Color3fArray || typeName == SdfValueTypeNames->Float4Array || typeName == SdfValueTypeNames->Color4fArray) { if (!_AssignColorSetPrimvarToMesh(mesh, primvar, meshFn)) { MGlobal::displayWarning( TfStringPrintf("Unable to retrieve and assign data for color set <%s> on mesh <%s>", name.GetText(), mesh.GetPrim().GetPath().GetText()).c_str()); } } } // We only vizualize the colorset by default if it is "displayColor". MStringArray colorSetNames; if (meshFn.getColorSetNames(colorSetNames)==MS::kSuccess) { for (unsigned int i=0; i < colorSetNames.length(); i++) { const MString colorSetName = colorSetNames[i]; if (std::string(colorSetName.asChar()) == PxrUsdMayaMeshColorSetTokens->DisplayColorColorSetName.GetString()) { MFnMesh::MColorRepresentation csRep= meshFn.getColorRepresentation(colorSetName); if (csRep==MFnMesh::kRGB || csRep==MFnMesh::kRGBA) { // both of these are needed to show the colorset. MPlug plg=meshFn.findPlug("displayColors"); if ( !plg.isNull() ) { plg.setBool(true); } meshFn.setCurrentColorSetName(colorSetName); } break; } } } // == Animate points == // Use blendShapeDeformer so that all the points for a frame are contained in a single node // if (pointsNumTimeSamples > 0) { MPointArray mayaPoints(mayaNumVertices); MObject meshAnimObj; MFnBlendShapeDeformer blendFn; MObject blendObj = blendFn.create(meshObj); if (context) { context->RegisterNewMayaNode( blendFn.name().asChar(), blendObj ); // used for undo/redo } for (unsigned int ti=0; ti < pointsNumTimeSamples; ++ti) { mesh.GetPointsAttr().Get(&points, pointsTimeSamples[ti]); for (unsigned int i=0; i < mayaNumVertices; i++) { mayaPoints.set( i, points[i][0], points[i][1], points[i][2] ); } // == Create Mesh Shape Node MFnMesh meshFn; if ( meshAnimObj.isNull() ) { meshAnimObj = meshFn.create(mayaPoints.length(), polygonCounts.length(), mayaPoints, polygonCounts, polygonConnects, mayaNodeTransformObj, &status ); if (status != MS::kSuccess) { continue; } } else { // Reuse the already created mesh by copying it and then setting the points meshAnimObj = meshFn.copy(meshAnimObj, mayaNodeTransformObj, &status); meshFn.setPoints(mayaPoints); } // Set normals if supplied // // NOTE: This normal information is not propagated through the blendShapes, only the controlPoints. // mesh.GetNormalsAttr().Get(&normals, pointsTimeSamples[ti]); if (normals.size() == static_cast<size_t>(meshFn.numFaceVertices()) && normalsFaceIds.length() == static_cast<size_t>(meshFn.numFaceVertices())) { MVectorArray mayaNormals(normals.size()); for (size_t i=0; i < normals.size(); i++) { mayaNormals.set( MVector(normals[i][0], normals[i][1], normals[i][2]), i); } if (meshFn.setFaceVertexNormals(mayaNormals, normalsFaceIds, polygonConnects) != MS::kSuccess) { } } // Add as target and set as an intermediate object blendFn.addTarget(meshObj, ti, meshAnimObj, 1.0); meshFn.setIntermediateObject(true); if (context) { context->RegisterNewMayaNode( meshFn.fullPathName().asChar(), meshAnimObj ); // used for undo/redo } } // Animate the weights so that mesh0 has a weight of 1 at frame 0, etc. MFnAnimCurve animFn; // Construct the time array to be used for all the keys MTimeArray timeArray; timeArray.setLength(pointsNumTimeSamples); for (unsigned int ti=0; ti < pointsNumTimeSamples; ++ti) { timeArray.set( MTime(pointsTimeSamples[ti]), ti); } // Key/Animate the weights MPlug plgAry = blendFn.findPlug( "weight" ); if ( !plgAry.isNull() && plgAry.isArray() ) { for (unsigned int ti=0; ti < pointsNumTimeSamples; ++ti) { MPlug plg = plgAry.elementByLogicalIndex(ti, &status); MDoubleArray valueArray(pointsNumTimeSamples, 0.0); valueArray[ti] = 1.0; // Set the time value where this mesh's weight should be 1.0 MObject animObj = animFn.create(plg, NULL, &status); animFn.addKeys(&timeArray, &valueArray); if (context) { context->RegisterNewMayaNode(animFn.name().asChar(), animObj ); // used for undo/redo } } } } return true; }
void liqRibData::addAdditionalSurfaceParameters( MObject node ) { LIQDEBUGPRINTF("-> scanning for additional rman surface attributes \n"); MStatus status = MS::kSuccess; unsigned i; // work out how many elements there would be in a facevarying array if a mesh or subD // faceVaryingCount is a private data member if ( ( type() == MRT_Mesh ) || ( type() == MRT_Subdivision ) ) { faceVaryingCount = 0; MFnMesh fnMesh( node ); for ( uint pOn = 0; pOn < fnMesh.numPolygons(); pOn++ ) { faceVaryingCount += fnMesh.polygonVertexCount( pOn ); } } // find how many additional MFnDependencyNode nodeFn( node ); // find the attributes MStringArray floatAttributesFound = findAttributesByPrefix( "rmanF", nodeFn ); MStringArray pointAttributesFound = findAttributesByPrefix( "rmanP", nodeFn ); MStringArray vectorAttributesFound = findAttributesByPrefix( "rmanV", nodeFn ); MStringArray normalAttributesFound = findAttributesByPrefix( "rmanN", nodeFn ); MStringArray colorAttributesFound = findAttributesByPrefix( "rmanC", nodeFn ); MStringArray stringAttributesFound = findAttributesByPrefix( "rmanS", nodeFn ); if ( floatAttributesFound.length() > 0 ) { for ( i = 0; i < floatAttributesFound.length(); i++ ) { liqTokenPointer tokenPointerPair; MString cutString = floatAttributesFound[i].substring(5, floatAttributesFound[i].length()); MPlug fPlug = nodeFn.findPlug( floatAttributesFound[i] ); MObject plugObj; status = fPlug.getValue( plugObj ); if ( plugObj.apiType() == MFn::kDoubleArrayData ) { MFnDoubleArrayData fnDoubleArrayData( plugObj ); MDoubleArray doubleArrayData = fnDoubleArrayData.array( &status ); tokenPointerPair.set( cutString.asChar(), rFloat, ( type() == MRT_Nurbs || type() == MRT_NuCurve ) ? true : false, true, false, doubleArrayData.length() ); for( unsigned int kk = 0; kk < doubleArrayData.length(); kk++ ) { tokenPointerPair.setTokenFloat( kk, doubleArrayData[kk] ); } if ( ( type() == MRT_NuCurve ) && ( cutString == MString( "width" ) ) ) { tokenPointerPair.setDetailType( rVarying); } else if ( ( ( type() == MRT_Mesh ) || ( type() == MRT_Subdivision ) ) && ( doubleArrayData.length() == faceVaryingCount ) ) { tokenPointerPair.setDetailType( rFaceVarying); } else { tokenPointerPair.setDetailType( rVertex ); } } else { if( fPlug.isArray() ) { int nbElts = fPlug.evaluateNumElements(); float floatValue; tokenPointerPair.set( cutString.asChar(), rFloat, ( type() == MRT_Nurbs || type() == MRT_NuCurve ) ? true : false, false, true, // philippe :passed as uArray, otherwise it will think it is a single float nbElts ); MPlug elementPlug; for( unsigned int kk = 0; kk < nbElts; kk++ ) { elementPlug = fPlug.elementByPhysicalIndex(kk); elementPlug.getValue( floatValue ); tokenPointerPair.setTokenFloat( kk, floatValue ); } tokenPointerPair.setDetailType( rConstant ); } else { float floatValue; tokenPointerPair.set( cutString.asChar(), rFloat, ( type() == MRT_Nurbs || type() == MRT_NuCurve ) ? true : false, false, false, 0 ); fPlug.getValue( floatValue ); tokenPointerPair.setTokenFloat( 0, floatValue ); tokenPointerPair.setDetailType( rConstant ); } } tokenPointerArray.push_back( tokenPointerPair ); } } if ( pointAttributesFound.length() > 0 ) { for ( i = 0; i < pointAttributesFound.length(); i++ ) { liqTokenPointer tokenPointerPair; MString cutString = pointAttributesFound[i].substring(5, pointAttributesFound[i].length()); MPlug pPlug = nodeFn.findPlug( pointAttributesFound[i] ); MObject plugObj; status = pPlug.getValue( plugObj ); if ( plugObj.apiType() == MFn::kPointArrayData ) { MFnPointArrayData fnPointArrayData( plugObj ); MPointArray pointArrayData = fnPointArrayData.array( &status ); tokenPointerPair.set( cutString.asChar(), rPoint, ( type() == MRT_Nurbs || type() == MRT_NuCurve ) ? true : false, true, false, pointArrayData.length() ); if ( type() == MRT_Nurbs || type() == MRT_NuCurve ) { for ( int kk = 0; kk < pointArrayData.length(); kk++ ) { tokenPointerPair.setTokenFloat( kk, pointArrayData[kk].x, pointArrayData[kk].y, pointArrayData[kk].z, pointArrayData[kk].w ); } } else { for ( int kk = 0; kk < pointArrayData.length(); kk++ ) { tokenPointerPair.setTokenFloat( kk, pointArrayData[kk].x, pointArrayData[kk].y, pointArrayData[kk].z ); } } tokenPointerPair.setDetailType( rVertex ); } else { // Hmmmm float ? double ? float x, y, z; tokenPointerPair.set( cutString.asChar(), rPoint, ( type() == MRT_Nurbs || type() == MRT_NuCurve ) ? true : false, false, false, 0 ); // Hmmm should check as for arrays if we are in nurbs mode : 4 values pPlug.child(0).getValue( x ); pPlug.child(1).getValue( y ); pPlug.child(2).getValue( z ); tokenPointerPair.setTokenFloat( 0, x, y, z ); tokenPointerPair.setDetailType( rConstant ); } tokenPointerArray.push_back( tokenPointerPair ); } } parseVectorAttributes( nodeFn, vectorAttributesFound, rVector ); parseVectorAttributes( nodeFn, normalAttributesFound, rNormal ); parseVectorAttributes( nodeFn, colorAttributesFound, rColor ); if ( stringAttributesFound.length() > 0 ) { for ( i = 0; i < stringAttributesFound.length(); i++ ) { liqTokenPointer tokenPointerPair; MString cutString = stringAttributesFound[i].substring(5, stringAttributesFound[i].length()); MPlug sPlug = nodeFn.findPlug( stringAttributesFound[i] ); MObject plugObj; status = sPlug.getValue( plugObj ); tokenPointerPair.set( cutString.asChar(), rString, ( type() == MRT_Nurbs || type() == MRT_NuCurve ) ? true : false, false, false, 0 ); MString stringVal; sPlug.getValue( stringVal ); tokenPointerPair.setTokenString( 0, stringVal.asChar(), stringVal.length() ); tokenPointerPair.setDetailType( rConstant ); tokenPointerArray.push_back( tokenPointerPair ); } } }
// returns 0 if static, 1 if sampled, and 2 if a curve int util::getSampledType(const MPlug& iPlug) { MPlugArray conns; iPlug.connectedTo(conns, true, false); // it's possible that only some element of an array plug or // some component of a compound plus is connected if (conns.length() == 0) { if (iPlug.isArray()) { unsigned int numConnectedElements = iPlug.numConnectedElements(); for (unsigned int e = 0; e < numConnectedElements; e++) { int retVal = getSampledType(iPlug.connectionByPhysicalIndex(e)); if (retVal > 0) return retVal; } } else if (iPlug.isCompound() && iPlug.numConnectedChildren() > 0) { unsigned int numChildren = iPlug.numChildren(); for (unsigned int c = 0; c < numChildren; c++) { int retVal = getSampledType(iPlug.child(c)); if (retVal > 0) return retVal; } } return 0; } MObject ob; MFnDependencyNode nodeFn; for (unsigned i = 0; i < conns.length(); i++) { ob = conns[i].node(); MFn::Type type = ob.apiType(); switch (type) { case MFn::kAnimCurveTimeToAngular: case MFn::kAnimCurveTimeToDistance: case MFn::kAnimCurveTimeToTime: case MFn::kAnimCurveTimeToUnitless: { nodeFn.setObject(ob); MPlug incoming = nodeFn.findPlug("i", true); // sampled if (incoming.isConnected()) return 1; // curve else return 2; } break; case MFn::kMute: { nodeFn.setObject(ob); MPlug mutePlug = nodeFn.findPlug("mute", true); // static if (mutePlug.asBool()) return 0; // curve else return 2; } break; default: break; } } return 1; }
// -------------------------------------------------------------------------------------------- MStatus polyModifierCmd::processTweaks( modifyPolyData& data ) // -------------------------------------------------------------------------------------------- { MStatus status = MS::kSuccess; // Clear tweak undo information (to be rebuilt) // fTweakIndexArray.clear(); fTweakVectorArray.clear(); // Extract the tweaks and place them into a polyTweak node. This polyTweak node // will be placed ahead of the modifier node to maintain the order of operations. // Special care must be taken into recreating the tweaks: // // 1) Copy tweak info (including connections!) // 2) Remove tweak info from both meshNode and a duplicate meshNode (if applicable) // 3) Cache tweak info for undo operations // //if( fHasTweaks && fHasHistory && !speedupTweakProcessing()) if( fHasTweaks && fHasHistory ) { // Declare our function sets // MFnDependencyNode depNodeFn; // Declare our attributes and plugs // MPlug meshTweakPlug; MPlug upstreamTweakPlug; MObject tweakNodeTweakAttr; // Declare our tweak processing variables // MPlug tweak; MPlug tweakChild; MObject tweakData; MObjectArray tweakDataArray; MFloatVector tweakVector; MIntArray tweakSrcConnectionCountArray; MPlugArray tweakSrcConnectionPlugArray; MIntArray tweakDstConnectionCountArray; MPlugArray tweakDstConnectionPlugArray; MPlugArray tempPlugArray; unsigned i; unsigned j; unsigned k; // Create the tweak node and get its attributes // data.tweakNode = fDGModifier.MDGModifier::createNode( "polyTweak" ); depNodeFn.setObject( data.tweakNode ); data.tweakNodeSrcAttr = depNodeFn.attribute( "output" ); data.tweakNodeDestAttr = depNodeFn.attribute( "inputPolymesh" ); tweakNodeTweakAttr = depNodeFn.attribute( "tweak" ); depNodeFn.setObject( data.meshNodeShape ); meshTweakPlug = depNodeFn.findPlug( "pnts" ); // ASSERT: meshTweakPlug should be an array plug! // MStatusAssert( (meshTweakPlug.isArray()), "meshTweakPlug.isArray() -- meshTweakPlug is not an array plug" ); unsigned numElements = meshTweakPlug.numElements(); // Gather meshTweakPlug data // for( i = 0; i < numElements; i++ ) { // MPlug::numElements() only returns the number of physical elements // in the array plug. Thus we must use elementByPhysical index when using // the index i. // tweak = meshTweakPlug.elementByPhysicalIndex(i); // If the method fails, the element is NULL. Only append the index // if it is a valid plug. // if( !tweak.isNull() ) { // Cache the logical index of this element plug // unsigned logicalIndex = tweak.logicalIndex(); // Collect tweak data and cache the indices and float vectors // tweak.getValue( tweakData ); tweakDataArray.append( tweakData ); getFloat3PlugValue( tweak, tweakVector ); fTweakIndexArray.append( logicalIndex ); fTweakVectorArray.append( tweakVector ); // Collect tweak connection data // // Parse down to the deepest level of the plug tree and check // for connections - look at the child nodes of the element plugs. // If any connections are found, record the connection and disconnect // it. // // ASSERT: The element plug should be compound! // MStatusAssert( (tweak.isCompound()), "tweak.isCompound() -- Element tweak plug is not compound" ); unsigned numChildren = tweak.numChildren(); for( j = 0; j < numChildren; j++ ) { tweakChild = tweak.child(j); if( tweakChild.isConnected() ) { // Get all connections with this plug as source, if they exist // tempPlugArray.clear(); if( tweakChild.connectedTo( tempPlugArray, false, true ) ) { unsigned numSrcConnections = tempPlugArray.length(); tweakSrcConnectionCountArray.append( numSrcConnections ); for( k = 0; k < numSrcConnections; k++ ) { tweakSrcConnectionPlugArray.append( tempPlugArray[k] ); fDGModifier.disconnect( tweakChild, tempPlugArray[k] ); } } else { tweakSrcConnectionCountArray.append(0); } // Get the connection with this plug as destination, if it exists // tempPlugArray.clear(); if( tweakChild.connectedTo( tempPlugArray, true, false ) ) { // ASSERT: tweakChild should only have one connection as destination! // MStatusAssert( (tempPlugArray.length() == 1), "tempPlugArray.length() == 1 -- 0 or >1 connections on tweakChild" ); tweakDstConnectionCountArray.append(1); tweakDstConnectionPlugArray.append( tempPlugArray[0] ); fDGModifier.disconnect( tempPlugArray[0], tweakChild ); } else { tweakDstConnectionCountArray.append(0); } } else { tweakSrcConnectionCountArray.append(0); tweakDstConnectionCountArray.append(0); } } } } // Apply meshTweakPlug data to our polyTweak node // MPlug polyTweakPlug( data.tweakNode, tweakNodeTweakAttr ); unsigned numTweaks = fTweakIndexArray.length(); int srcOffset = 0; int dstOffset = 0; //Progress initialisieren progressBar progress("Processing Tweaks", numTweaks); for( i = 0; i < numTweaks; i++ ) { // Apply tweak data // tweak = polyTweakPlug.elementByLogicalIndex( fTweakIndexArray[i] ); tweak.setValue( tweakDataArray[i] ); // ASSERT: Element plug should be compound! // MStatusAssert( (tweak.isCompound()), "tweak.isCompound() -- Element plug, 'tweak', is not compound" ); unsigned numChildren = tweak.numChildren(); for( j = 0; j < numChildren; j++ ) { tweakChild = tweak.child(j); // Apply tweak source connection data // if( 0 < tweakSrcConnectionCountArray[i*numChildren + j] ) { for( k = 0; k < (unsigned) tweakSrcConnectionCountArray[i*numChildren + j]; k++ ) { fDGModifier.connect( tweakChild, tweakSrcConnectionPlugArray[srcOffset] ); srcOffset++; } } // Apply tweak destination connection data // if( 0 < tweakDstConnectionCountArray[i*numChildren + j] ) { fDGModifier.connect( tweakDstConnectionPlugArray[dstOffset], tweakChild ); dstOffset++; } } if(i%50 == 0) { progress.set(i); } } // Now, set the tweak values on the meshNode(s) to zero (History dependent) // MFnNumericData numDataFn; MObject nullVector; // Create a NULL vector (0,0,0) using MFnNumericData to pass into the plug // numDataFn.create( MFnNumericData::k3Float ); numDataFn.setData( 0, 0, 0 ); nullVector = numDataFn.object(); for( i = 0; i < numTweaks; i++ ) { // Access using logical indices since they are the only plugs guaranteed // to hold tweak data. // tweak = meshTweakPlug.elementByLogicalIndex( fTweakIndexArray[i] ); tweak.setValue( nullVector ); } // Only have to clear the tweaks off the duplicate mesh if we do not have history // and we want history. // if( !fHasHistory && fHasRecordHistory ) { depNodeFn.setObject( data.upstreamNodeShape ); upstreamTweakPlug = depNodeFn.findPlug( "pnts" ); if( !upstreamTweakPlug.isNull() ) { for( i = 0; i < numTweaks; i++ ) { tweak = meshTweakPlug.elementByLogicalIndex( fTweakIndexArray[i] ); tweak.setValue( nullVector ); } } } } else fHasTweaks = false; return status; }
// -------------------------------------------------------------------------------------------- MStatus polyModifierCmd::cacheMeshTweaks() // -------------------------------------------------------------------------------------------- { MStatus status = MS::kSuccess; // Clear tweak undo information (to be rebuilt) // fTweakIndexArray.clear(); fTweakVectorArray.clear(); // Extract the tweaks and store them in our local tweak cache members // if( fHasTweaks ) { // Declare our function sets // MFnDependencyNode depNodeFn; MObject meshNode = fDagPath.node(); MPlug meshTweakPlug; // Declare our tweak processing variables // MPlug tweak; MPlug tweakChild; MObject tweakData; MObjectArray tweakDataArray; MFloatVector tweakVector; MPlugArray tempPlugArray; unsigned i; depNodeFn.setObject( meshNode ); meshTweakPlug = depNodeFn.findPlug( "pnts" ); // ASSERT: meshTweakPlug should be an array plug! // MStatusAssert( (meshTweakPlug.isArray()), "meshTweakPlug.isArray() -- meshTweakPlug is not an array plug" ); unsigned numElements = meshTweakPlug.numElements(); // Gather meshTweakPlug data // for( i = 0; i < numElements; i++ ) { // MPlug::numElements() only returns the number of physical elements // in the array plug. Thus we must use elementByPhysical index when using // the index i. // tweak = meshTweakPlug.elementByPhysicalIndex(i); // If the method fails, the element is NULL. Only append the index // if it is a valid plug. // if( !tweak.isNull() ) { // Cache the logical index of this element plug // unsigned logicalIndex = tweak.logicalIndex(); // Collect tweak data and cache the indices and float vectors // getFloat3PlugValue( tweak, tweakVector ); fTweakIndexArray.append( logicalIndex ); fTweakVectorArray.append( tweakVector ); } } } return status; }
/* static */ bool PxrUsdMayaTranslatorCurves::Create( const UsdGeomCurves& curves, MObject parentNode, const PxrUsdMayaPrimReaderArgs& args, PxrUsdMayaPrimReaderContext* context) { if (not curves) { return false; } const UsdPrim& prim = curves.GetPrim(); MStatus status; // Create node (transform) MObject mayaNodeTransformObj; if (not PxrUsdMayaTranslatorUtil::CreateTransformNode(prim, parentNode, args, context, &status, &mayaNodeTransformObj)) { return false; } VtArray<GfVec3f> points; VtArray<int> curveOrder; VtArray<int> curveVertexCounts; VtArray<float> curveWidths; VtArray<GfVec2d> curveRanges; VtArray<double> curveKnots; // LIMITATION: xxx REVISIT xxx // Non-animated Attrs // Assuming that a number of these USD attributes are assumed to not be animated // Some we may want to expose as animatable later. // curves.GetCurveVertexCountsAttr().Get(&curveVertexCounts); // not animatable // XXX: // Only supporting single curve for now. // Sanity Checks if (curveVertexCounts.size() == 0) { MGlobal::displayError( TfStringPrintf("VertexCount arrays is empty on NURBS curves <%s>. Skipping...", prim.GetPath().GetText()).c_str()); return false; // No verts for the curve, so exit } else if (curveVertexCounts.size() > 1) { MGlobal::displayWarning( TfStringPrintf("Multiple curves in <%s>. Reading first one...", prim.GetPath().GetText()).c_str()); } int curveIndex = 0; curves.GetWidthsAttr().Get(&curveWidths); // not animatable // Gather points. If args.GetReadAnimData() is TRUE, // pick the first avaiable sample or default UsdTimeCode pointsTimeSample=UsdTimeCode::EarliestTime(); std::vector<double> pointsTimeSamples; size_t numTimeSamples = 0; if (args.GetReadAnimData()) { curves.GetPointsAttr().GetTimeSamples(&pointsTimeSamples); numTimeSamples = pointsTimeSamples.size(); if (numTimeSamples>0) { pointsTimeSample = pointsTimeSamples[0]; } } curves.GetPointsAttr().Get(&points, pointsTimeSample); if (points.size() == 0) { MGlobal::displayError( TfStringPrintf("Points arrays is empty on NURBS curves <%s>. Skipping...", prim.GetPath().GetText()).c_str()); return false; // invalid nurbscurves, so exit } if (UsdGeomNurbsCurves nurbsSchema = UsdGeomNurbsCurves(prim)) { nurbsSchema.GetOrderAttr().Get(&curveOrder); // not animatable nurbsSchema.GetKnotsAttr().Get(&curveKnots); // not animatable nurbsSchema.GetRangesAttr().Get(&curveRanges); // not animatable } else { // Handle basis curves originally modelled in Maya as nurbs. curveOrder.resize(1); UsdGeomBasisCurves basisSchema = UsdGeomBasisCurves(prim); TfToken typeToken; basisSchema.GetTypeAttr().Get(&typeToken); if (typeToken == UsdGeomTokens->linear) { curveOrder[0] = 2; curveKnots.resize(points.size()); for (size_t i=0; i < curveKnots.size(); ++i) { curveKnots[i] = i; } } else { curveOrder[0] = 4; // Strip off extra end points; assuming this is non-periodic. VtArray<GfVec3f> tmpPts(points.size() - 2); std::copy(points.begin() + 1, points.end() - 1, tmpPts.begin()); points.swap(tmpPts); // Cubic curves in Maya have numSpans + 2*3 - 1, and for geometry // that came in as basis curves, we have numCV's - 3 spans. See the // MFnNurbsCurve documentation and the nurbs curve export // implementation in mojitoplugmaya for more details. curveKnots.resize(points.size() -3 + 5); int knotIdx = 0; for (size_t i=0; i < curveKnots.size(); ++i) { if (i < 3) { curveKnots[i] = 0.0; } else { if (i <= curveKnots.size() - 3) { ++knotIdx; } curveKnots[i] = double(knotIdx); } } } } // == Convert data size_t mayaNumVertices = points.size(); MPointArray mayaPoints(mayaNumVertices); for (size_t i=0; i < mayaNumVertices; i++) { mayaPoints.set( i, points[i][0], points[i][1], points[i][2] ); } double *knots=curveKnots.data(); MDoubleArray mayaKnots( knots, curveKnots.size()); int mayaDegree = curveOrder[curveIndex] - 1; MFnNurbsCurve::Form mayaCurveForm = MFnNurbsCurve::kOpen; // HARDCODED bool mayaCurveCreate2D = false; bool mayaCurveCreateRational = true; // == Create NurbsCurve Shape Node MFnNurbsCurve curveFn; MObject curveObj = curveFn.create(mayaPoints, mayaKnots, mayaDegree, mayaCurveForm, mayaCurveCreate2D, mayaCurveCreateRational, mayaNodeTransformObj, &status ); if (status != MS::kSuccess) { return false; } MString nodeName( prim.GetName().GetText() ); nodeName += "Shape"; curveFn.setName(nodeName, false, &status); std::string nodePath( prim.GetPath().GetText() ); nodePath += "/"; nodePath += nodeName.asChar(); if (context) { context->RegisterNewMayaNode( nodePath, curveObj ); // used for undo/redo } // == Animate points == // Use blendShapeDeformer so that all the points for a frame are contained in a single node // Almost identical code as used with MayaMeshReader.cpp // if (numTimeSamples > 0) { MPointArray mayaPoints(mayaNumVertices); MObject curveAnimObj; MFnBlendShapeDeformer blendFn; MObject blendObj = blendFn.create(curveObj); if (context) { context->RegisterNewMayaNode(blendFn.name().asChar(), blendObj ); // used for undo/redo } for (unsigned int ti=0; ti < numTimeSamples; ++ti) { curves.GetPointsAttr().Get(&points, pointsTimeSamples[ti]); for (unsigned int i=0; i < mayaNumVertices; i++) { mayaPoints.set( i, points[i][0], points[i][1], points[i][2] ); } // == Create NurbsCurve Shape Node MFnNurbsCurve curveFn; if ( curveAnimObj.isNull() ) { curveAnimObj = curveFn.create(mayaPoints, mayaKnots, mayaDegree, mayaCurveForm, mayaCurveCreate2D, mayaCurveCreateRational, mayaNodeTransformObj, &status ); if (status != MS::kSuccess) { continue; } } else { // Reuse the already created curve by copying it and then setting the points curveAnimObj = curveFn.copy(curveAnimObj, mayaNodeTransformObj, &status); curveFn.setCVs(mayaPoints); } blendFn.addTarget(curveObj, ti, curveAnimObj, 1.0); curveFn.setIntermediateObject(true); if (context) { context->RegisterNewMayaNode( curveFn.fullPathName().asChar(), curveAnimObj ); // used for undo/redo } } // Animate the weights so that curve0 has a weight of 1 at frame 0, etc. MFnAnimCurve animFn; // Construct the time array to be used for all the keys MTimeArray timeArray; timeArray.setLength(numTimeSamples); for (unsigned int ti=0; ti < numTimeSamples; ++ti) { timeArray.set( MTime(pointsTimeSamples[ti]), ti); } // Key/Animate the weights MPlug plgAry = blendFn.findPlug( "weight" ); if ( !plgAry.isNull() && plgAry.isArray() ) { for (unsigned int ti=0; ti < numTimeSamples; ++ti) { MPlug plg = plgAry.elementByLogicalIndex(ti, &status); MDoubleArray valueArray(numTimeSamples, 0.0); valueArray[ti] = 1.0; // Set the time value where this curve's weight should be 1.0 MObject animObj = animFn.create(plg, NULL, &status); animFn.addKeys(&timeArray, &valueArray); if (context) { context->RegisterNewMayaNode(animFn.name().asChar(), animObj ); // used for undo/redo } } } } return true; }
void ShadingNetworkExporter::createShader(const MObject& node) { MStatus status; MFnDependencyNode depNodeFn(node); const OSLShaderInfo *shaderInfo = ShadingNodeRegistry::getShaderInfo(depNodeFn.typeName()); if(!shaderInfo) { std::cout << "Skipping unsupported shader: " << depNodeFn.typeName() << "\n"; return; } if(m_shadersExported.count(depNodeFn.name()) != 0) { std::cout << "Skipping already exported shader: " << depNodeFn.name() << "\n"; return; } m_shadersExported.insert(depNodeFn.name()); asr::ParamArray shaderParams; for(int i = 0, e = shaderInfo->paramInfo.size(); i < e; ++i) { const OSLParamInfo& paramInfo = shaderInfo->paramInfo[i]; // Skip output attributes. if(paramInfo.isOutput) { std::cout << "Skipping output attribute: " << "\n"; std::cout << paramInfo << std::endl; continue; } if(!paramInfo.validDefault) { std::cout << "Skipping attribute without valid default: " << "\n"; std::cout << paramInfo << std::endl; continue; } if(paramInfo.isArray) { std::cout << "Skipping array attribute: " << "\n"; std::cout << paramInfo << std::endl; continue; } MPlug plug = depNodeFn.findPlug(paramInfo.mayaAttributeName, &status); if(!status) { std::cout << "Skipping unknown attribute: " << paramInfo.mayaAttributeName << std::endl; continue; } if(plug.isConnected()) { MObject srcNode; if(AttributeUtils::get(plug, srcNode)) createShader(srcNode); continue; } if(plug.isCompound() && plug.numConnectedChildren() != 0) { std::cout << "Skipping connected compound attribute: " << plug.name() << "\n"; continue; } if(plug.isArray() && plug.numConnectedElements() != 0) { std::cout << "Skipping connected array attribute: " << plug.name() << "\n"; continue; } processAttribute(plug, paramInfo, shaderParams); } m_shaderGroup->add_shader( shaderInfo->shaderType.asChar(), shaderInfo->shaderName.asChar(), depNodeFn.name().asChar(), shaderParams); }
void ShadingNetworkExporter::addConnections(const MObject& node) { MStatus status; MFnDependencyNode depNodeFn(node); const OSLShaderInfo *shaderInfo = ShadingNodeRegistry::getShaderInfo(depNodeFn.typeName()); if(!shaderInfo) { std::cout << "Skipping unsupported shader: " << depNodeFn.typeName() << "\n"; return; } if(m_shadersExported.count(depNodeFn.name()) != 0) { std::cout << "Skipping already exported shader: " << depNodeFn.name() << "\n"; return; } m_shadersExported.insert(depNodeFn.name()); for(int i = 0, e = shaderInfo->paramInfo.size(); i < e; ++i) { const OSLParamInfo& paramInfo = shaderInfo->paramInfo[i]; // Skip output attributes. if(paramInfo.isOutput) continue; MPlug plug = depNodeFn.findPlug(paramInfo.mayaAttributeName, &status); if(!status) { std::cout << "Skipping unknown attribute: " << paramInfo.mayaAttributeName << std::endl; continue; } if(plug.isConnected()) { MPlug srcPlug; if(AttributeUtils::getPlugConnectedTo(plug, srcPlug)) { MFnDependencyNode srcDepNodeFn(srcPlug.node()); const OSLShaderInfo *srcShaderInfo = ShadingNodeRegistry::getShaderInfo(srcDepNodeFn.typeName()); if(!srcShaderInfo) continue; if(const OSLParamInfo *srcParamInfo = srcShaderInfo->findParam(srcPlug.name())) { m_shaderGroup->add_connection( srcDepNodeFn.name().asChar(), srcParamInfo->paramName.asChar(), depNodeFn.name().asChar(), paramInfo.paramName.asChar()); } addConnections(srcPlug.node()); } } if(plug.isCompound() && plug.numConnectedChildren() != 0) { // ??? } if(plug.isArray() && plug.numConnectedElements() != 0) { // ??? } } }
bool FxAttributeFiller::FillPlug( DXCCEffectPath& parameter, MPlug& plug ) { HRESULT hr= S_OK; LPDXCCRESOURCE pResource= NULL; LPDIRECT3DBASETEXTURE9 pTexture= NULL; D3DXPARAMETER_DESC desc= parameter.End->Description; float NumericVals[16]= {0.0f}; MString StringVal; LPCSTR StringValStr= ""; bool RestoreFound= false; LPCVOID pRestoreData= NULL; size_t RestoreSize= 0; CComPtr<IDXCCPropertyCollection> pCollection; DXCCPROPERTY_KEY key= 0; if(Restore) { if( DXCC_SUCCEEDED( Restore->GetPath( parameter.End->LongPathName, &pCollection, &key) ) ) { pCollection->GetPropertyValueAsData(key, &pRestoreData); DXCCPROPERTY_DESC desc= pCollection->GetPropertyDesc(key); if(desc == DXCCPD_STRING) { StringVal= (LPCSTR)pRestoreData; StringValStr= (LPCSTR)pRestoreData; RestoreFound= true; } else { size_t RestoreSize= DXCCPropertySize( desc, pRestoreData ); memcpy( NumericVals, pRestoreData, RestoreSize); RestoreFound= true; } } } if((desc.Type == D3DXPT_BOOL) ||(desc.Type == D3DXPT_INT) ||(desc.Type == D3DXPT_FLOAT)) { if(!RestoreFound) { if(plug.isArray()) { hr= Shader->Effect->GetFloatArray(parameter.End->Handle, NumericVals, 16); if(DXCC_FAILED(hr)) DXCC_GOTO_EXIT(e_Exit, TRUE); } else { hr= Shader->Effect->GetFloat(parameter.End->Handle, NumericVals); if(DXCC_FAILED(hr)) DXCC_GOTO_EXIT(e_Exit, TRUE); } } if(plug.isArray()) { int count= desc.Rows * desc.Columns; for(int i= 0; i < count; i++) { MPlug subPlug= plug.elementByLogicalIndex(i); DXCHECK_MSTATUS(subPlug.setValue( NumericVals[i] )); } } else { DXCHECK_MSTATUS(plug.setValue( NumericVals[0] )); } } else if((desc.Type == D3DXPT_TEXTURE) ||(desc.Type == D3DXPT_TEXTURE1D) ||(desc.Type == D3DXPT_TEXTURE2D) ||(desc.Type == D3DXPT_TEXTURE3D) ||(desc.Type == D3DXPT_TEXTURECUBE)) { if(!RestoreFound) { hr= Shader->Effect->GetTexture(parameter.End->Handle, &pTexture); if(DXCC_SUCCEEDED(hr) && pTexture != NULL) { hr= g_PreviewPipeline.AccessManager()->FindResourceByPointer( (LPUNKNOWN)pTexture, NULL, &pResource); if(DXCC_SUCCEEDED(hr)) { StringVal= pResource->GetResourcePath(); } } else { D3DXHANDLE hResourceAddy= Shader->Effect->GetAnnotationByName( parameter.End->Handle, "SasResourceAddress"); if(hResourceAddy) { LPCSTR resourceAddressStr= NULL; Shader->Effect->GetString(hResourceAddy, &resourceAddressStr); StringVal= resourceAddressStr; } } } DXCHECK_MSTATUS(plug.setValue( StringVal )); } else if(desc.Type == D3DXPT_STRING) { if(!RestoreFound) { hr= Shader->Effect->GetString(parameter.End->Handle, &StringValStr); StringVal= StringValStr; } DXCHECK_MSTATUS(plug.setValue( StringVal )); } else { DXCC_STATUS_EXIT(hr, E_FAIL, e_Exit, TRUE); } e_Exit: DXCC_RELEASE(pResource); DXCC_RELEASE(pTexture); return DXCC_SUCCEEDED(hr); }