Пример #1
0
/*!
 * Description:   Deform the point using the Sederberg-Parry FFD algorithm.
 *
 * Arguments:
 *  block       : the datablock of the node
 *  iter        : an iterator for the geometry to be deformed
 *  m           : matrix to transform the point into world space
 *  multiIndex  : the index of the geometry that we are deforming
 */
MStatus ffdPlanar::deform( MDataBlock& block,
                          MItGeometry& iter,
                          const MMatrix& /*m*/,
                          unsigned int multiIndex )
{
    MStatus status = MS::kSuccess;
    
    // Determine the displacement lattice points.
    MDataHandle row1Data = block.inputValue( latticeRow1, &status );
    MCheckErr( status, "Error getting r1 data handle\n" );
    MVector row1Vector = row1Data.asVector();
    
    MDataHandle row2Data = block.inputValue( latticeRow2, &status );
    MCheckErr( status, "Error getting r2 data handle\n" );
    MVector row2Vector = row2Data.asVector();
    
    MDataHandle row3Data = block.inputValue( latticeRow3, &status );
    MCheckErr( status, "Error getting r3 data\n" );
    MVector row3Vector = row3Data.asVector();

    // Determine the envelope (this is a global scale factor for the deformer).
    MDataHandle envData = block.inputValue(envelope,&status);
    MCheckErr(status, "Error getting envelope data handle\n");
    float env = envData.asFloat();
    
    // Generate the FFD lattice.
    MVector lattice[FFD_LATTICE_POINTS_S][FFD_LATTICE_POINTS_T][FFD_LATTICE_POINTS_U] = { // Since dimensions known ahead of time, generate array now.
        { // x = 0
            { MVector(0.f, row1Vector.x, 0.f), MVector(0.f, row1Vector.y, .5f), MVector(0.f, row1Vector.z, 1.f) }, // y = 0
        },
        { // x = 1
            { MVector(.5f, row2Vector.x, 0.f), MVector(.5f, row2Vector.y, .5f), MVector(.5f, row2Vector.z, 1.f) }, // y = 0
        },
        { // x = 2
            { MVector(1.f, row3Vector.x, 0.f), MVector(1.f, row3Vector.y, .5f), MVector(1.f, row3Vector.z, 1.f) }, // y = 0
        }
    };
    
    MBoundingBox boundingBox;
    status = getBoundingBox( block, multiIndex, boundingBox );
    MCheckErr( status, "Error getting bounding box\n" );
    
    MTransformationMatrix transform = getXyzToStuTransformation( boundingBox );
    MMatrix transformMatrix = transform.asMatrix();
    MMatrix inverseMatrix = transform.asMatrixInverse();
    
    // Iterate through each point in the geometry.
    for ( ; !iter.isDone(); iter.next() )
    {
        MPoint pt = iter.position();
        MPoint ptStu = pt * transformMatrix;
        MPoint deformed = getDeformedPoint( ptStu, lattice ) * inverseMatrix;

        if ( env != 1.f )
        {
            MVector diff = deformed - pt;
            deformed = pt + env * diff;
        }
        
        iter.setPosition( deformed );
    }
    return status;
}
void GlobalComponent::updateComponent(MDGModifier & dgMod,bool forceUpdate, bool globalPos) {
    MStatus status;
    if( !this->m_metaDataNode.isNull() ) {
        //get the rig name
        MFnDependencyNode metaDataNodeFn( m_metaDataNode );
        MString metaNodeName = metaDataNodeFn.name();
        MStringArray nameArray;
        metaNodeName.split('_', nameArray);
        MString rigName = nameArray[1];
        //get the controller name
        MString controllerName = nameArray[2];
        MString compXmlName = this->m_pCompGuide->getName();
        //update names of component objects
        if( rigName != this->m_rigName || controllerName != compXmlName ) {
            //set the metadata node name
            lrutils::stringReplaceAll(metaNodeName, rigName, this->m_rigName);
            lrutils::stringReplaceAll(metaNodeName, controllerName, this->m_pCompGuide->getName());
            metaDataNodeFn.setName(metaNodeName);
            //set controller object name
            MObject globalCtlObj;
            lrutils::getMetaNodeConnection(this->m_metaDataNode, globalCtlObj, "controller");
            MFnDependencyNode globalCtlFn( globalCtlObj );
            MString globalCtlName = globalCtlFn.name();
            lrutils::stringReplaceAll(globalCtlName, rigName, this->m_rigName);
            lrutils::stringReplaceAll(globalCtlName, controllerName, this->m_pCompGuide->getName());
            globalCtlFn.setName(globalCtlName);
            //set controller group object name
            MObject globalCtlGroupObj;
            lrutils::getMetaNodeConnection(this->m_metaDataNode, globalCtlGroupObj, "controllerGroup");
            MFnDependencyNode globalCtlGroupFn( globalCtlGroupObj );
            MString globalCtlGroupName = globalCtlGroupFn.name();
            lrutils::stringReplaceAll(globalCtlGroupName, rigName, this->m_rigName);
            lrutils::stringReplaceAll(globalCtlGroupName, controllerName, this->m_pCompGuide->getName());
            globalCtlGroupFn.setName(globalCtlGroupName);
            //set rigParentConstraint object name
            MObject rigParentConstraintObj;
            lrutils::getMetaNodeConnection(this->m_metaDataNode, rigParentConstraintObj, "rigParentConstraint");
            MFnDependencyNode rigParentConstraintFn( rigParentConstraintObj );
            MString rigParentConstraintName = rigParentConstraintFn.name();
            lrutils::stringReplaceAll(rigParentConstraintName, rigName, this->m_rigName);
            lrutils::stringReplaceAll(rigParentConstraintName, controllerName, this->m_pCompGuide->getName());
            rigParentConstraintFn.setName(rigParentConstraintName);
            //set rigScaleConstraint object name
            MObject rigScaleConstraintObj;
            lrutils::getMetaNodeConnection(this->m_metaDataNode, rigScaleConstraintObj, "rigScaleConstraint");
            MFnDependencyNode rigScaleConstraintFn( rigScaleConstraintObj );
            MString rigScaleConstraintName = rigScaleConstraintFn.name();
            lrutils::stringReplaceAll(rigScaleConstraintName, rigName, this->m_rigName);
            lrutils::stringReplaceAll(rigScaleConstraintName, controllerName, this->m_pCompGuide->getName());
            rigScaleConstraintFn.setName(rigScaleConstraintName);
            //set noTransformScaleConstraint object name
            MObject noTransformScaleConstraintObj;
            lrutils::getMetaNodeConnection(this->m_metaDataNode, noTransformScaleConstraintObj, "noTransformScaleConstraint");
            MFnDependencyNode noTransformScaleConstraintFn( noTransformScaleConstraintObj );
            MString noTransformScaleConstraintName = noTransformScaleConstraintFn.name();
            lrutils::stringReplaceAll(noTransformScaleConstraintName, rigName, this->m_rigName);
            lrutils::stringReplaceAll(noTransformScaleConstraintName, controllerName, this->m_pCompGuide->getName());
            noTransformScaleConstraintFn.setName(noTransformScaleConstraintName); 
        }
        //update component settings, if the version increment is raised
        //or force update is true
        MPlug versionPlug = metaDataNodeFn.findPlug( "version" );
        float nodeVersion; 
        versionPlug.getValue(nodeVersion);
        if( (this->m_pCompGuide->getVersion() > nodeVersion) || forceUpdate ) {
            versionPlug.setValue( this->m_pCompGuide->getVersion() );
            //make a new controller object based upon the xml settings    
            GlobalComponentGuidePtr globalGuide = boost::dynamic_pointer_cast<GlobalComponentGuide>(this->m_pCompGuide);
            MString ctlColor = globalGuide->getColor();
            MString ctlIcon = globalGuide->getIcon();

            MGlobal::executeCommand( "python(\"control = rig101().rig101WCGetByName('" + ctlIcon + "')\");" );
            MGlobal::executeCommand( "python(\"Utils.setControllerColor(control, '" + ctlColor + "')\");" );
            MCommandResult res;
            MGlobal::executeCommand( MString("python(\"control.fullPath()\");"), res );        
            MString sResult;
            res.getResult(sResult);
            MObject ctlObj;
            MStatus status = lrutils::getObjFromName(sResult, ctlObj);
            MyCheckStatus(status, "lrutils::getObjFromName() failed");
            //apply the scale of the controller location to the new shape
            MVectorArray ctlLocation = this->m_pCompGuide->getLocation(0);
            MFnTransform ctlFn( ctlObj );
            lrutils::setLocation(ctlObj, ctlLocation, MFnTransform::MFnTransform(), false, false, true);


            //get the global transforms of the controller for all keyframes and save them for later use
            MObject oldCtlObj;
            status = lrutils::getMetaNodeConnection( this->m_metaDataNode, oldCtlObj, "controller" );
            MyCheckStatus(status, "getMetaNodeConnection() failed");
            MFnTransform oldCtlFn( oldCtlObj );
            std::map<double, MMatrix> oldCtlWorldMatrices;
            if(globalPos) {
                status = lrutils::getAllWorldTransforms(oldCtlObj, oldCtlWorldMatrices);
                MyCheckStatus(status, "lrutils::getAllWorldTransforms() failed");
            }

            //get the shape node of the original controller object
            MStringArray sResults;
            MGlobal::executeCommand( "listRelatives -s -fullPath "+oldCtlFn.name()+";", sResults );
            MString oldCtlShapePath = sResults[0];
            MGlobal::executeCommand( "listRelatives -s -path "+oldCtlFn.name()+";", sResults );
            MString oldCtlShapeName = sResults[0];
            MObject oldCtlShapeObj; lrutils::getObjFromName(oldCtlShapePath, oldCtlShapeObj);
            //delete the old shape node
            MGlobal::deleteNode( oldCtlShapeObj );
            //get the new shape node
            MGlobal::executeCommand( "listRelatives -s -fullPath "+ctlFn.name()+";", sResults );
            MString ctlShapePath = sResults[0];
            MObject ctlShapeObj; lrutils::getObjFromName(ctlShapePath, ctlShapeObj);
            //instance the new shape node under the old controller node
            MString command = "parent -s -add " + ctlShapePath + " " + oldCtlFn.name() + ";";
            MGlobal::executeCommand( command );
            MFnDependencyNode ctlShapeFn( ctlShapeObj );
            ctlShapeFn.setName( oldCtlShapeName );
            //set the old controller group translation to the new location
            MObject oldCtlGroupObj;
            lrutils::getMetaNodeConnection( this->m_metaDataNode, oldCtlGroupObj, "controllerGroup" );
            MFnTransform oldCtlGroupFn( oldCtlGroupObj );
            //save the original old controller position
            MTransformationMatrix oldXForm = oldCtlGroupFn.transformation();
            lrutils::setLocation(oldCtlGroupObj, ctlLocation, oldCtlGroupFn, true, true, false);
            //compute the inverse transformation matrix of the old control group
            MTransformationMatrix oldCtlGrpXform = oldCtlGroupFn.transformation();
            MTransformationMatrix inverseXform = MTransformationMatrix(oldCtlGrpXform.asMatrixInverse());
            //set the target offset for the rigParentConstraint node
            lrutils::getMetaNodeConnection(this->m_metaDataNode, this->m_rigParentConstraint, "rigParentConstraint");
            lrutils::setParentConstraintOffset( this->m_rigParentConstraint, inverseXform );
            //delete the new controller transform
            MGlobal::deleteNode( ctlObj );
            
            //find the global transformation matrix of the controller group
            MDagPath groupPath;
            status = oldCtlGroupFn.getPath(groupPath);
            MyCheckStatus(status, "MFnDagNode.getPath() failed");
            MMatrix oldCtlGroupWorldMatrix = groupPath.inclusiveMatrix(&status);
            MyCheckStatus(status, "MDagPath.inclusiveMatrix() failed");
            if(globalPos) {
                //update the animation curves attached to the old controller
                lrutils::updateAnimCurves(oldCtlObj, oldCtlWorldMatrices, oldCtlGroupWorldMatrix);
            }
        }
    }
}