예제 #1
0
        //    Description:
        //        Given a clipboard and an ifstream, read the ifstream and add
        //        all of the anim curves described in ther stream into the
        //        API clipboard.
        //
        public void readClipboard(ref StreamReaderExt readAnim, MAnimCurveClipboard cb)
        {
            //	Set the default values for the start and end of the clipboard.
            //	The MAnimCurveClipboard::set() method will examine all of the
            //	anim curves are determine the proper start and end values, if the
            //	start time is greater than the end value.
            //
            //	By default, the start values are greater than the end values to
            //	ensure correct behavior if the file does not specify the start and
            //	end values.
            //
            double startTime = 1.0;
            double endTime = 0.0;
            double startUnitless = 1.0;
            double endUnitless = 0.0;

            resetUnits();
            convertAnglesFromV2To3 = false;
            convertAnglesFromV3To2 = false;

            //	Read the header. The header officially ends when the first non-header
            //	keyword is found. The header contains clipboard specific information
            //	where the body is anim curve specific.
            //
            string dataType = "";
            bool hasVersionString = false;
            while (!readAnim.EndOfStream)
            {
                advance(ref readAnim);
                dataType = asWord(ref readAnim);

                if (string.Compare(dataType, kAnimVersion) == 0)
                {
                    string version = asWord(ref readAnim);
                    animVersion = Convert.ToDouble(version);
                    string thisVersion = kAnimVersionString;

                    hasVersionString = true;

                    //	Add versioning control here.
                    //
                    if (version != thisVersion)
                    {
                        // Use format to place variable string into message
                        string msgFmt = MStringResource.getString(RegisterMStringResources.kInvalidVersion);
                        string msg = string.Format(msgFmt, thisVersion, version);
                        MGlobal.displayWarning(msg);
                    }
                }
                else if (string.Compare(dataType, kMayaVersion) == 0)
                {
                    string version = asWord(ref readAnim, true);
                    string currentVersion = MGlobal.mayaVersion;
                    if (currentVersion.Substring(0, 2) == "2.")
                    {
                        string vCheck = version.Substring(0, 2);
                        if (vCheck != "2.")
                            convertAnglesFromV3To2 = true;
                    }
                    else
                    {
                        //	If this is a pre-Maya 3.0 file, then the tangent angles
                        //	will need to be converted to work in Maya 3.0+
                        //
                        string vCheck = version.Substring(0, 2);
                        if (vCheck == "2.")
                        {
                            convertAnglesFromV2To3 = true;
                        }
                    }
                }
                else if (string.Compare(dataType, kTimeUnit) == 0)
                {
                    string timeUnitString = asWord(ref readAnim);
                    if (!animUnitNames.setFromName(timeUnitString, ref timeUnit))
                    {
                        string unitName = "";
                        timeUnit = MTime.uiUnit;
                        animUnitNames.setToShortName(timeUnit, ref unitName);
                        // Use format to place variable string into message
                        string msgFmt = MStringResource.getString(RegisterMStringResources.kSettingToUnit);
                        string msg = string.Format(msgFmt, kTimeUnit, unitName);
                        MGlobal.displayWarning(msg);
                    }
                }
                else if (string.Compare(dataType, kLinearUnit) == 0)
                {
                    string linearUnitString = asWord(ref readAnim);
                    if (!animUnitNames.setFromName(linearUnitString, ref linearUnit))
                    {
                        string unitName = "";
                        linearUnit = MDistance.uiUnit;
                        animUnitNames.setToShortName(linearUnit, ref unitName);

                        // Use format to place variable string into message
                        string msgFmt = MStringResource.getString(RegisterMStringResources.kSettingToUnit);
                        string msg = string.Format(msgFmt, kLinearUnit, unitName);
                        MGlobal.displayWarning(msg);
                    }
                }
                else if (string.Compare(dataType, kAngularUnit) == 0)
                {
                    string angularUnitString = asWord( ref readAnim);
                    if (!animUnitNames.setFromName(angularUnitString, ref angularUnit))
                    {
                        string unitName = "";
                        angularUnit = MAngle.uiUnit;
                        animUnitNames.setToShortName(angularUnit, ref unitName);

                        // Use format to place variable string into message
                        string msgFmt = MStringResource.getString(RegisterMStringResources.kSettingToUnit);
                        string msg = string.Format(msgFmt, kAngularUnit, unitName);
                        MGlobal.displayWarning(msg);
                    }
                }
                else if (string.Compare(dataType, kStartTime) == 0)
                    startTime = asDouble(ref readAnim);
                else if (string.Compare(dataType, kEndTime) == 0)
                    endTime = asDouble(ref readAnim);
                else if (string.Compare(dataType, kStartUnitless) == 0)
                    startUnitless = asDouble(ref readAnim);
                else if (string.Compare(dataType, kEndUnitless) == 0)
                    endUnitless = asDouble(ref readAnim);
                else {
                    //	The header should be finished. Begin to parse the body.
                    //
                    break;
                }
            }

            //	The animVersion string is required.
            //
            if (!hasVersionString)
            {
                // Use format to place variable string into message
                string msgFmt = MStringResource.getString(RegisterMStringResources.kMissingKeyword);
                string msg = string.Format(msgFmt, kAnimVersion);
                throw new ArgumentException(msg, "cb");
            }

            //	Set the linear and angular units to be the same as the file
            //	being read. This will allow fixed tangent data to be read
            //	in properly if the scene has different units than the .anim file.
            //
            MDistance.Unit oldDistanceUnit = MDistance.uiUnit;
            MTime.Unit oldTimeUnit = MTime.uiUnit;

            MDistance.uiUnit = linearUnit;
            MTime.uiUnit = timeUnit;

            MAnimCurveClipboardItemArray clipboardArray = new MAnimCurveClipboardItemArray();
            while (!readAnim.EndOfStream)
            {

                if ("" == dataType) {
                    dataType = asWord(ref readAnim);
                }

                if (string.Compare(dataType, kAnim) == 0)
                {
                    string fullAttributeName = "", leafAttributeName="", nodeName = "";

                    //	If this is from an unconnected anim curve, then there
                    //	will not be an attribute name.
                    //
                    if (!isNextNumeric(ref readAnim))
                    {
                        fullAttributeName = asWord(ref readAnim);

                        //	If the node names were specified, then the next two
                        //	words should be the leaf attribute and the node name.
                        //
                        if (!isNextNumeric(ref readAnim))
                        {
                            leafAttributeName = asWord(ref readAnim);
                            nodeName = asWord(ref readAnim);
                        }
                    }

                    uint rowCount, childCount, attrCount;
                    rowCount = (uint)asDouble(ref readAnim);
                    childCount = (uint)asDouble(ref readAnim);
                    attrCount = (uint)asDouble(ref readAnim);

                    //	If the next keyword is not an animData, then this is
                    //	a place holder for the API clipboard.
                    //
                    dataType = asWord(ref readAnim);
                    if (string.Compare(dataType, kAnimData) == 0)
                    {
                        MAnimCurveClipboardItem clipboardItem = new MAnimCurveClipboardItem();
                        if (readAnimCurve(ref readAnim, ref clipboardItem))
                        {
                            clipboardItem.setAddressingInfo(rowCount,
                                                            childCount, attrCount);
                            clipboardItem.setNameInfo(	nodeName,
                                                        fullAttributeName,
                                                        leafAttributeName);
                            clipboardArray.append(clipboardItem);
                        }
                        else
                        {
                            //	Could not read the anim curve.
                            //
                            string msg = MStringResource.getString(RegisterMStringResources.kCouldNotReadAnim);
                            MGlobal.displayError(msg);
                        }
                    }
                    else
                    {
                        //	This must be a place holder object for the clipboard.
                        //
                        MAnimCurveClipboardItem clipboardItem = new MAnimCurveClipboardItem();
                        clipboardItem.setAddressingInfo(rowCount,
                                                        childCount, attrCount);

                        //	Since there is no anim curve specified, what is
                        //	in the fullAttributeName string is really the node
                        //	name.
                        //
                        clipboardItem.setNameInfo(	fullAttributeName,
                                                    nodeName,
                                                    leafAttributeName);
                        clipboardArray.append(clipboardItem);

                        //	dataType already contains the next keyword.
                        //
                        continue;
                    }
                }
                else
                {
                    if (!readAnim.EndOfStream)
                    {
                        string warnStr = dataType;

                        // Use format to place variable string into message
                        string msgFmt = MStringResource.getString(RegisterMStringResources.kUnknownKeyword);
                        string msg = string.Format(msgFmt, warnStr);
                        MGlobal.displayError(msg);

                        //	Skip to the next line, this one is invalid.
                        //
                        readAnim.ReadLine();
                    }
                    else
                    {
                        //	The end of the file was reached.
                        //
                        break;
                    }
                }

                //	Skip any whitespace.
                //
                dataType = "";
            }

            try
            {
                cb.set(	clipboardArray,
                        new MTime(startTime, timeUnit), new MTime(endTime, timeUnit),
                        (float) startUnitless, (float) endUnitless) ;
            }
            catch (System.Exception)
            {
                string msg = MStringResource.getString(RegisterMStringResources.kClipboardFailure);
                MGlobal.displayError(msg);
            }

            //	Restore the old units.
            //
            MDistance.uiUnit = oldDistanceUnit;
            MTime.uiUnit = oldTimeUnit;
        }
예제 #2
0
        //    Description:
        //        Read a block of the stream that should contain anim curve
        //        data in the format determined by the animData keyword.
        //
        protected bool readAnimCurve(ref StreamReaderExt clipFile, ref MAnimCurveClipboardItem item)
        {
            MFnAnimCurve animCurve = new MFnAnimCurve();
            MObject animCurveObj = new MObject();

            //	Anim curve defaults.
            //
            animBase.AnimBaseType input = wordAsInputType(kWordTypeTime);
            animBase.AnimBaseType output = wordAsOutputType(kWordTypeLinear);
            MFnAnimCurve.InfinityType preInf = wordAsInfinityType(kWordConstant);
            MFnAnimCurve.InfinityType postInf = wordAsInfinityType(kWordConstant);

            string inputUnitName = "";
            animUnitNames.setToShortName(timeUnit, ref inputUnitName);
            string outputUnitName = "";
            MAngle.Unit tanAngleUnit = angularUnit;
            bool isWeighted = false;

            string dataType = "";

            while (!clipFile.EndOfStream)
            {
                advance(ref clipFile);

                dataType = asWord(ref clipFile);

                if (string.Compare(dataType, kInputString) == 0) {
                    input = wordAsInputType(asWord(ref clipFile));
                } else if (string.Compare(dataType, kOutputString) == 0) {
                    output = wordAsOutputType(asWord(ref clipFile));
                } else if (string.Compare(dataType, kWeightedString) == 0) {
                    isWeighted = (asDouble(ref clipFile) == 1.0);
                } else if (string.Compare(dataType, kPreInfinityString) == 0) {
                    preInf = wordAsInfinityType(asWord(ref clipFile));
                } else if (string.Compare(dataType, kPostInfinityString) == 0) {
                    postInf = wordAsInfinityType(asWord(ref clipFile));
                } else if (string.Compare(dataType, kInputUnitString) == 0) {
                    inputUnitName = asWord(ref clipFile);
                } else if (string.Compare(dataType, kOutputUnitString) == 0) {
                    outputUnitName = asWord(ref clipFile);
                } else if (string.Compare(dataType, kTanAngleUnitString) == 0) {
                    string tUnit = asWord(ref clipFile);
                    if (!animUnitNames.setFromName(tUnit, ref tanAngleUnit)) {
                        string unitName="";
                        tanAngleUnit = angularUnit;
                        animUnitNames.setToShortName(tanAngleUnit, ref unitName);

                        // Use format to place variable string into message
                        string msgFmt = MStringResource.getString(RegisterMStringResources.kSettingTanAngleUnit);
                        string msg = string.Format(msgFmt, unitName);
                        MGlobal.displayError(msg);
                    }
                } else if (string.Compare(dataType, kKeysString) == 0) {
                    //	Ignore the rest of this line.
                    //
                    clipFile.ReadLine();
                    break;
                } else if (string.Compare(dataType, "{") == 0) {
                    //	Skippping the '{' character. Just ignore it.
                    //
                    continue;
                } else {
                    //	An unrecogized keyword was found.
                    //
                    string warnStr = (dataType);
                    // Use format to place variable string into message
                    string msgFmt = MStringResource.getString(RegisterMStringResources.kUnknownKeyword);
                    string msg = string.Format(msgFmt, warnStr);
                    MGlobal.displayError(msg);
                    continue;
                }
            }

            // Read the animCurve
            //
            MFnAnimCurve.AnimCurveType type = typeAsAnimCurveType(input, output);
            try
            {
                animCurveObj = animCurve.create(type,null);
            }
            catch (System.Exception )
            {
                string msg = MStringResource.getString(RegisterMStringResources.kCouldNotCreateAnim);
                MGlobal.displayError(msg);
                return false;
            }

            animCurve.setIsWeighted(isWeighted);
            animCurve.setPreInfinityType(preInf);
            animCurve.setPostInfinityType(postInf);

            //	Set the appropriate units.
            //
            MTime.Unit inputTimeUnit = MTime.Unit.kInvalid;
            if (input == AnimBaseType.kAnimBaseTime)
            {
                if (!animUnitNames.setFromName(inputUnitName, ref inputTimeUnit))
                {
                    string unitName = "";
                    inputTimeUnit = timeUnit;
                    animUnitNames.setToShortName(inputTimeUnit, ref unitName);
                    // Use format to place variable string into message
                    string msgFmt = MStringResource.getString(RegisterMStringResources.kSettingToUnit);
                    string msg = string.Format(msgFmt, kInputUnitString, unitName);
                    MGlobal.displayWarning(msg);
                }
            }

            MTime.Unit outputTimeUnit= MTime.Unit.kInvalid;
            if (output == AnimBaseType.kAnimBaseTime)
            {
                if (!animUnitNames.setFromName(outputUnitName, ref outputTimeUnit))
                {
                    string unitName = "";
                    outputTimeUnit = timeUnit;
                    animUnitNames.setToShortName(outputTimeUnit, ref unitName);
                    // Use format to place variable string into message
                    string msgFmt = MStringResource.getString(RegisterMStringResources.kSettingToUnit);
                    string msg = string.Format(msgFmt, kOutputUnitString, unitName);
                    MGlobal.displayWarning(msg);
                }
            }

            uint index = 0;
            double conversion = 1.0;
            if (output == AnimBaseType.kAnimBaseLinear)
            {
                MDistance.Unit unit = MDistance.Unit.kInvalid;
                if (outputUnitName.Length != 0)
                {
                    if (!animUnitNames.setFromName(outputUnitName, ref unit))
                    {
                        string unitName = "";
                        unit = linearUnit;
                        animUnitNames.setToShortName(unit, ref unitName);
                        // Use format to place variable string into message
                        string msgFmt = MStringResource.getString(RegisterMStringResources.kSettingToUnit);
                        string msg = string.Format(msgFmt, kOutputUnitString, unitName);
                        MGlobal.displayWarning(msg);
                    }
                }
                else
                    unit = linearUnit;

                if (unit != MDistance.Unit.kCentimeters)
                {
                    MDistance one = new MDistance(1.0, unit);
                    conversion = one.asCentimeters;
                }
            }
            else if (output == AnimBaseType.kAnimBaseAngular)
            {
                MAngle.Unit unit = MAngle.Unit.kInvalid;
                if (outputUnitName.Length != 0)
                {
                    if (!animUnitNames.setFromName(outputUnitName, ref unit))
                    {
                        string unitName = "";
                        unit = angularUnit;
                        animUnitNames.setToShortName(unit, ref unitName);
                        // Use format to place variable string into message
                        string msgFmt = MStringResource.getString(RegisterMStringResources.kSettingToUnit);
                        string msg = string.Format(msgFmt, kOutputUnitString, unitName);
                        MGlobal.displayWarning(msg);
                    }
                }
                else
                    unit = angularUnit;

                if (unit != MAngle.Unit.kRadians)
                {
                    MAngle one = new MAngle(1.0, unit);
                    conversion = one.asRadians;
                }
            }

            // Now read each keyframe
            //
            advance(ref clipFile);
            char c = (char)clipFile.Peek();
            while (!clipFile.EndOfStream && c != kBraceRightChar)
            {
                double t = asDouble(ref clipFile);
                double val = asDouble(ref clipFile);

                MFnAnimCurve.TangentType tanIn = wordAsTangentType(asWord(ref clipFile));
                MFnAnimCurve.TangentType tanOut = wordAsTangentType(asWord(ref clipFile));

                switch (type)
                {
                    case MFnAnimCurve.AnimCurveType.kAnimCurveTT:
                        index = animCurve.addKey(	new MTime(val, inputTimeUnit),
                                                    new MTime(val, outputTimeUnit),
                                                    tanIn, tanOut, null);
                        break;
                    case MFnAnimCurve.AnimCurveType.kAnimCurveTL:
                    case MFnAnimCurve.AnimCurveType.kAnimCurveTA:
                    case MFnAnimCurve.AnimCurveType.kAnimCurveTU:
                        index = animCurve.addKey(	new MTime(t, inputTimeUnit),
                                                    val*conversion, tanIn, tanOut,
                                                    null);
                        break;
                    case MFnAnimCurve.AnimCurveType.kAnimCurveUL:
                    case MFnAnimCurve.AnimCurveType.kAnimCurveUA:
                    case MFnAnimCurve.AnimCurveType.kAnimCurveUU:
                        index = animCurve.addKey(	t, val*conversion,
                                                    tanIn, tanOut,
                                                    null);
                        break;
                    case MFnAnimCurve.AnimCurveType.kAnimCurveUT:
                        index = animCurve.addKey(	t, new MTime(val, outputTimeUnit),
                                                    tanIn, tanOut,
                                                    null);
                        break;
                    default:
                        string msg = MStringResource.getString(RegisterMStringResources.kUnknownNode);
                        MGlobal.displayError(msg);
                        return false;
                }

                //	Tangent locking needs to be called after the weights and
                //	angles are set for the fixed tangents.
                //
                bool tLocked = asDouble(ref clipFile) == 1.0;
                bool swLocked = asDouble(ref clipFile) == 1.0;
                bool isBreakdown = false;
                if (animVersion >= kVersionNonWeightedAndBreakdowns)
                {
                    isBreakdown = (asDouble(ref clipFile) == 1.0);
                }

                //	Only fixed tangents need additional information.
                //
                if (tanIn == MFnAnimCurve.TangentType.kTangentFixed)
                {
                    MAngle inAngle = new MAngle(asDouble(ref clipFile), tanAngleUnit);
                    double inWeight = asDouble(ref clipFile);

                    //	If this is from a pre-Maya3.0 file, the tangent angles will
                    //	need to be converted.
                    //
                    if (convertAnglesFromV2To3) {
                        convertAnglesAndWeights2To3(type,isWeighted,ref inAngle,ref inWeight);
                    } else if (convertAnglesFromV3To2) {
                        convertAnglesAndWeights3To2(type,isWeighted,ref inAngle,ref inWeight);
                    }

                    //  By default, the tangents are locked. When the tangents
                    //	are locked, setting the angle and weight of a fixed in
                    //	tangent may change the tangent type of the out tangent.
                    //
                    animCurve.setTangentsLocked(index, false);
                    animCurve.setTangent(index, inAngle, inWeight, true);
                }

                //	Only fixed tangents need additional information.
                //
                if (tanOut == MFnAnimCurve.TangentType.kTangentFixed)
                {
                    MAngle outAngle = new MAngle(asDouble(ref clipFile), tanAngleUnit);
                    double outWeight = asDouble(ref clipFile);

                    //	If this is from a pre-Maya3.0 file, the tangent angles will
                    //	need to be converted.
                    //
                    if (convertAnglesFromV2To3) {
                        convertAnglesAndWeights2To3(type,isWeighted,ref outAngle,ref outWeight);
                    } else if (convertAnglesFromV3To2) {
                        convertAnglesAndWeights3To2(type,isWeighted,ref outAngle,ref outWeight);
                    }

                    //  By default, the tangents are locked. When the tangents
                    //	are locked, setting the angle and weight of a fixed out
                    //	tangent may change the tangent type of the in tangent.
                    //
                    animCurve.setTangentsLocked(index, false);
                    animCurve.setTangent(index, outAngle, outWeight, false);
                }

                //	To prevent tangent types from unexpectedly changing, tangent
                //	locking should be the last operation. See the above comments
                //	about fixed tangent types for more information.
                //
                animCurve.setWeightsLocked(index, swLocked);
                animCurve.setTangentsLocked(index, tLocked);
                animCurve.setIsBreakdown (index, isBreakdown);

                //	There should be no additional data on this line. Go to the
                //	next line of data.
                //
                clipFile.ReadLine();

                //	Skip any comments.
                //
                advance(ref clipFile);
                c = (char)clipFile.Peek();
            }

            //	Ignore the brace that marks the end of the keys block.
            //
            if (c == kBraceRightChar) {
                clipFile.ReadLine();
            }

            //	Ignore the brace that marks the end of the animData block.
            //
            advance(ref clipFile);
            if ( (char)clipFile.Peek() == kBraceRightChar) {
                clipFile.ReadLine();
            }
            else {
                //	Something is wrong.
                //
                string msg = MStringResource.getString(RegisterMStringResources.kMissingBrace);
                MGlobal.displayError(msg);
            }

            //	Do not set the clipboard with an empty clipboard item.
            //
            if (!animCurveObj.isNull) {
                item.animCurve = animCurveObj;
            }

            //	Delete the copy of the anim curve.
            //
            MGlobal.deleteNode(animCurveObj);

            return true;
        }
예제 #3
0
        //    Description:
        //        Write out the anim curve from the clipboard item into the
        //        stream. The position of the anim curve in the clipboard
        //        and the attribute to which it is attached is written out in this
        //        method.
        //
        //        This method returns true if the write was successful.
        //
        protected void writeAnim( ref StreamWriter clip, 
            MAnimCurveClipboardItem clipboardItem,
            bool placeHolder = false,
            bool nodeNames = false)
        {
            if (clip == null)
            {
                throw new ArgumentNullException( "clip" );
            }

            clip.Write(kAnim);

            //	If this is a clipboard place holder then there will be no full
            //	or leaf attribute names.
            //
            if (placeHolder)
            {
                clip.Write(kSpaceChar + clipboardItem.nodeName );
            }
            else
            {
                clip.Write(kSpaceChar + clipboardItem.fullAttributeName);

                if (nodeNames)
                {
                    clip.Write( kSpaceChar + clipboardItem.leafAttributeName);
                    clip.Write( kSpaceChar + clipboardItem.nodeName );
                }
            }

            uint rowCount = 0, childCount = 0, attrCount = 0;
            clipboardItem.getAddressingInfo(ref rowCount, ref childCount, ref attrCount);

            clip.Write( kSpaceChar);
            clip.Write(rowCount);
            clip.Write(kSpaceChar);
            clip.Write(childCount);
            clip.Write(kSpaceChar);
            clip.Write(attrCount);
            clip.Write(kSemiColonChar);
            clip.Write(Environment.NewLine);
        }
예제 #4
0
		protected void writeAnim( ref StreamWriter clip, 
							 MAnimCurveClipboardItem clipboardItem,
							bool placeHolder = false,
							bool nodeNames = false)
		//	Description:
		//		Write out the anim curve from the clipboard item into the 
		//		stream. The position of the anim curve in the clipboard
		//		and the attribute to which it is attached is written out in this
		//		method.
		//
		//		This method returns true if the write was successful.
		//
		{
			if (clip == null)
			{
				throw new ArgumentNullException( "clip" );
			}

			clip.Write(kAnim);

			//	If this is a clipboard place holder then there will be no full
			//	or leaf attribute names.
			//
			if (placeHolder)
			{
				clip.Write(kSpaceChar + clipboardItem.nodeName );
			} 
			else 
			{
				clip.Write(kSpaceChar + clipboardItem.fullAttributeName);

				if (nodeNames) 
				{
					clip.Write( kSpaceChar + clipboardItem.leafAttributeName);
					clip.Write( kSpaceChar + clipboardItem.nodeName );
				}
			}

			uint rowCount = 0, childCount = 0, attrCount = 0;
			clipboardItem.getAddressingInfo(ref rowCount, ref childCount, ref attrCount);

			clip.Write( kSpaceChar);
			clip.Write(rowCount);
			clip.Write(kSpaceChar);
			clip.Write(childCount);
			clip.Write(kSpaceChar);
			clip.Write(attrCount);
			clip.Write(kSemiColonChar);
			clip.Write(Environment.NewLine);
		}