MStatus lrutils::makeHomeNull(MObject obj, MFnTransform& transformFn, MObject& groupObj) { MStatus status = MS::kFailure; status = transformFn.setObject(obj); MyCheckStatusReturn(status, "invalid MObject provided for MFnTransform.setObject()"); if( status == MS::kSuccess ) { MDagModifier dagMod; groupObj = dagMod.createNode( "transform", MObject::kNullObj, &status ); MyCheckStatusReturn(status, "MDagModifier.createNode() failed"); dagMod.doIt(); MFnTransform groupFn; groupFn.setObject(groupObj); groupFn.set(transformFn.transformation()); groupFn.addChild(obj); MString groupName = transformFn.name(); groupName = groupName.substring(0, groupName.numChars() - 4); groupName += "GRP"; groupFn.setName(groupName); } return status; }
// // This callback gets called for the PostToolChanged and SelectionChanged events. // It checks to see if the current context is the dragAttrContext, which is the context // applied by default when a custom numeric attribute is selected in the channel box. // In this case, the customAttrManip context is set. // static void eventCB(void * data) { // This check prevents recursion from happening when overriding the manip. if (isSetting) return; MSelectionList selList; MGlobal::getActiveSelectionList(selList); MString curCtx = ""; MGlobal::executeCommand("currentCtx", curCtx); MDagPath path; MObject dependNode; for (unsigned int i=0; i<selList.length(); i++) { if ((selList.getDependNode(i, dependNode)) == MStatus::kSuccess) { MFnTransform node; if (node.hasObj(dependNode)) node.setObject(dependNode); else continue; if (node.typeId() == rockingTransformNode::id) { // If the current context is the dragAttrContext, check to see // if the custom channel box attributes are selected. If so, // attach the custom manipulator. if ((curCtx == "dragAttrContext") || (curCtx == "")) { // Make sure that the correct channel box attributes are selected // before setting the tool context. unsigned int c; MStringArray cboxAttrs; MGlobal::executeCommand( "channelBox -q -selectedMainAttributes $gChannelBoxName", cboxAttrs); for (c=0; c<cboxAttrs.length(); c++) { if (cboxAttrs[c] == customAttributeString) { isSetting = true; MGlobal::executeCommand("setToolTo myCustomAttrContext"); isSetting = false; return; } } } if ((curCtx == "moveSuperContext") || (curCtx == "manipMoveContext") || (curCtx == "")) { isSetting = true; MGlobal::executeCommand("setToolTo myCustomTriadContext"); isSetting = false; return; } } } } }
MStatus lrutils::makeGroup(MObject & obj, MString name) { MStatus status = MS::kFailure; MDagModifier dagMod; MObject groupObj = dagMod.createNode( "transform", MObject::kNullObj, &status ); MyCheckStatusReturn(status, "MDagModifier.createNode() failed"); dagMod.doIt(); MFnTransform groupFn; groupFn.setObject(groupObj); MString groupName = name; groupName += "_GRP"; groupFn.setName(groupName); obj = groupObj; return status; }
MStatus lrutils::setParentConstraintOffset(MObject constraintObj, MTransformationMatrix transform) { MStatus status = MS::kFailure; MFnTransform constraintFn; status = constraintFn.setObject( constraintObj ); MyCheckStatusReturn(status, "invalid MObject provided for MFnTransform.setObject()"); MString constraintName = constraintFn.name(); if ( status = MS::kSuccess ) { MVector vTranslation = transform.getTranslation(MSpace::kTransform); MGlobal::executeCommand( "setAttr \""+constraintName+".target[0].targetOffsetTranslateX\" "+vTranslation.x+";"); MGlobal::executeCommand( "setAttr \""+constraintName+".target[0].targetOffsetTranslateY\" "+vTranslation.y+";"); MGlobal::executeCommand( "setAttr \""+constraintName+".target[0].targetOffsetTranslateZ\" "+vTranslation.z+";"); double* rotation = new double[3]; MTransformationMatrix::RotationOrder rotOrder = MTransformationMatrix::kXYZ; transform.getRotation(rotation,rotOrder); MGlobal::executeCommand( "setAttr \""+constraintName+".target[0].targetOffsetRotateX\" "+rotation[0]+";"); MGlobal::executeCommand( "setAttr \""+constraintName+".target[0].targetOffsetRotateY\" "+rotation[1]+";"); MGlobal::executeCommand( "setAttr \""+constraintName+".target[0].targetOffsetRotateZ\" "+rotation[2]+";"); } return status; }
MStatus lrutils::setLocation(MObject obj, MVectorArray location, MFnTransform& transformFn, bool translate, bool rotation, bool scale) { MStatus status = MS::kFailure; status = transformFn.setObject(obj); MyCheckStatusReturn(status, "invalid MObject provided for MFnTransform.setObject()"); if( status == MS::kSuccess ) { if(translate) { MVector vTranslation = location[0] ; //stringstream text; text << "(" << vTranslation.x << ", " << vTranslation.y << ", " << vTranslation.z << ")"; //MGlobal::displayInfo( text.str().c_str() ); status = transformFn.setTranslation(vTranslation, MSpace::kTransform); stringstream text; text << "MFnTransform.setTranslation() failed, status code [" << status.errorString().asChar() << "]"; MyCheckStatusReturn(status, text.str().c_str() ); vTranslation = transformFn.getTranslation(MSpace::kWorld); //text.clear(); text << "(" << vTranslation.x << ", " << vTranslation.y << ", " << vTranslation.z << ")"; //MGlobal::displayInfo( text.str().c_str() ); } if(rotation) { MVector vRotation = location[1]*3.141592/180.0; MEulerRotation eRotation = MEulerRotation(vRotation); status = transformFn.setRotation(eRotation); } if(scale) { MVector vScale = location[2]; double* scale = new double[3]; vScale.get(scale); transformFn.setScale(scale); //make the scale of the controller the identity MGlobal::executeCommand("select -r "+transformFn.name()+";"); MGlobal::executeCommand("makeIdentity -s true -apply true;"); } } return status; }
MStatus simulateBoids::doIt( const MArgList& args ) { // Description: implements the MEL boids command // Arguments: args - the argument list that was passes to the command from MEL MStatus status = MS::kSuccess; /**************************************** * building thread/dll data structure * ****************************************/ InfoCache infoCache; SimulationParameters simParams; RulesParameters *applyingRules; double progressBar=0; double aov=pi/3; int i,numberOfDesires=0; // params retrievement MSelectionList sel; MObject node; MFnDependencyNode nodeFn; MFnTransform locatorFn; MPlug plug; // simulation params int simulationLengthValue; // [int] in seconds int framesPerSecondValue; // [int] int startFrameValue; // [int] int boidsNumberValue; // [int] // export params MString logFilePathValue; // [char *] MString logFileNameValue; // [char *] int logFileTypeValue; // 0 = nCache; 1 = log file; 2 = XML; // locomotion params int locomotionModeValue; // [int] double maxSpeedValue; // [double] double maxForceValue; // [double] // double mass=1; // [double] MTime currentTime, maxTime; MPlug plugX, plugY, plugZ; double tx, ty, tz; int frameLength ; Vector * leader = NULL; MStatus leaderFound=MStatus::kFailure; MGlobal::getActiveSelectionList(sel); for ( MItSelectionList listIter(sel); !listIter.isDone(); listIter.next() ) { listIter.getDependNode(node); switch(node.apiType()) { case MFn::kTransform: // get locator transform to follow leaderFound=locatorFn.setObject(node); cout << locatorFn.name().asChar() << " is selected as locator" << endl; break; case MFn::kPluginDependNode: nodeFn.setObject(node); cout << nodeFn.name().asChar() << " is selected as brain" << endl; break; default: break; } cout<< node.apiTypeStr()<<endl; } // rules params setRuleVariables(alignment); setRuleVariables(cohesion); setRuleVariables(separation); setRuleVariables(follow); getPlugValue(simulationLength); getPlugValue(framesPerSecond); getPlugValue(startFrame); getPlugValue(boidsNumber); getPlugValue(logFileType); getRulePlugValue(alignment); getRulePlugValue(cohesion); getRulePlugValue(separation); getRulePlugValue(follow); getPlugValue(locomotionMode); getPlugValue(maxSpeed); getPlugValue(maxForce); getTypePlugValue(logFilePath); getTypePlugValue(logFileName); // counting active rules number if(alignmentActiveValue) numberOfDesires++; if(cohesionActiveValue) numberOfDesires++; if(separationActiveValue) numberOfDesires++; if(followActiveValue) numberOfDesires++; currentTime = MTime((double)startFrameValue); // MAnimControl::minTime(); maxTime = MTime((double)(startFrameValue + (simulationLengthValue * framesPerSecondValue))); // MAnimControl::maxTime(); cout << "time unit enum (6 is 24 fps): " << currentTime.unit() << endl; plugX = locatorFn.findPlug( MString( "translateX" ), &status ); plugY = locatorFn.findPlug( MString( "translateY" ), &status ); plugZ = locatorFn.findPlug( MString( "translateZ" ), &status ); frameLength = simulationLengthValue * framesPerSecondValue; if(leaderFound==MS::kSuccess) { leader = new Vector[frameLength]; while ( currentTime < maxTime ) { { int index = (int)currentTime.value() - startFrameValue; /* MGlobal::viewFrame(currentTime); pos = locatorFn.getTranslation(MSpace::kWorld); cout << "pos: " << pos.x << " " << pos.y << " " << pos.z << endl; */ status = plugX.getValue( tx, MDGContext(currentTime) ); status = plugY.getValue( ty, MDGContext(currentTime) ); status = plugZ.getValue( tz, MDGContext(currentTime) ); leader[index].x = tx; leader[index].y = ty; leader[index].z = tz; //cout << "pos at time " << currentTime.value() << " has x: " << tx << " y: " << ty << " z: " << tz << endl; currentTime++; } } } simParams.fps=framesPerSecondValue; simParams.lenght=simulationLengthValue; simParams.numberOfBoids=boidsNumberValue; simParams.maxAcceleration=maxForceValue; simParams.maxVelocity=maxSpeedValue; simParams.simplifiedLocomotion=TRUE; applyingRules=new RulesParameters[numberOfDesires]; // cache settings MString saveString; saveString = logFilePathValue+"/"+logFileNameValue; infoCache.fileName=new char[saveString.length()+1]; memcpy(infoCache.fileName,saveString.asChar(),sizeof(char)*(saveString.length()+1)); infoCache.cacheFormat=ONEFILE; infoCache.fps=framesPerSecondValue; infoCache.start=startFrameValue/framesPerSecondValue; infoCache.end=simulationLengthValue+infoCache.start; infoCache.loging=FALSE; infoCache.option=POSITIONVELOCITY; infoCache.particleSysName="BoidsNParticles"; infoCache.saveMethod=MAYANCACHE; for(i=0;i<numberOfDesires;i++) { applyingRules[i].enabled=TRUE; applyingRules[i].precedence=1; applyingRules[i].aov=aov; applyingRules[i].visibilityOption=FALSE; } if(cohesionActiveValue==0) applyingRules[COHESIONRULE].enabled=FALSE; else { applyingRules[COHESIONRULE].ruleName=COHESIONRULE; applyingRules[COHESIONRULE].ruleFactor=cohesionFactorValue; applyingRules[COHESIONRULE].ruleRadius=cohesionRadiusValue; applyingRules[COHESIONRULE].ruleWeight=cohesionWeightValue; } if(separationActiveValue==0) applyingRules[SEPARATIONRULE].enabled=FALSE; else { applyingRules[SEPARATIONRULE].ruleName=SEPARATIONRULE; applyingRules[SEPARATIONRULE].ruleFactor=separationFactorValue; applyingRules[SEPARATIONRULE].ruleRadius=separationRadiusValue; applyingRules[SEPARATIONRULE].ruleWeight=separationWeightValue; } if(alignmentActiveValue==0) applyingRules[ALIGNMENTRULE].enabled=FALSE; else { applyingRules[ALIGNMENTRULE].ruleName=ALIGNMENTRULE; applyingRules[ALIGNMENTRULE].ruleFactor=alignmentFactorValue; applyingRules[ALIGNMENTRULE].ruleRadius=alignmentRadiusValue; applyingRules[ALIGNMENTRULE].ruleWeight=alignmentWeightValue; } if(followActiveValue==0) applyingRules[FOLLOWRULE].enabled=FALSE; else { applyingRules[FOLLOWRULE].ruleName=FOLLOWRULE; applyingRules[FOLLOWRULE].ruleRadius=followRadiusValue; applyingRules[FOLLOWRULE].ruleFactor=followFactorValue; applyingRules[FOLLOWRULE].ruleWeight=followWeightValue; } // initializing simulation parameters boidInit(numberOfDesires, applyingRules, simParams , infoCache, leader); DLLData datadll; // preparing threads pool status = MThreadPool::init(); if (status==MStatus::kSuccess) { MThreadPool::newParallelRegion(ThreadsCreator, &datadll); setResult( "Command executed!\n" ); CHECK_MSTATUS(MProgressWindow::endProgress()); MThreadPool::release(); } switch(datadll.result) { case 0: status=MS::kSuccess; break; default: status=MS::kFailure; } MThreadPool::release(); return status; }
MStatus splineSolverNode::preSolve() { MStatus stat; setRotatePlane(false); setSingleChainOnly(true); setPositionOnly(false); //Get Handle MIkHandleGroup * handle_group = handleGroup(); if (NULL == handle_group) { return MS::kFailure; } MObject handle = handle_group->handle( 0 ); MDagPath handlePath = MDagPath::getAPathTo( handle ); fnHandle.setObject( handlePath ); //Get Curve MPlug inCurvePlug = fnHandle.findPlug( "inCurve" ); MDataHandle curveHandle = inCurvePlug.asMDataHandle(); MObject inputCurveObject = curveHandle.asNurbsCurveTransformed(); curveFn.setObject( inputCurveObject ); float initCurveLength = curveFn.length(); MVector initNormal = curveFn.normal(0); MVector initTangent = curveFn.tangent(0); float stretchRatio = 1; // Get the position of the end_effector // MDagPath effectorPath; fnHandle.getEffector(effectorPath); tran.setObject( effectorPath ); // Get the start joint position // MDagPath startJointPath; fnHandle.getStartJoint( startJointPath ); joints.clear(); //Get Joints while (true) { effectorPath.pop(); joints.push_back( effectorPath ); if (effectorPath == startJointPath) break; } std::reverse(joints.begin(), joints.end()); if (!fnHandle.hasAttribute("str")) { //Add Custom Attributes to Handle MFnNumericAttribute fnAttr; MObject attr = fnAttr.create("stretchRatio", "str", MFnNumericData::kDouble, stretchRatio); fnAttr.setKeyable(1); fnAttr.setWritable(1); fnAttr.setMin(0); fnAttr.setMax(1); fnAttr.setHidden(0); fnAttr.setStorable(1); fnAttr.setReadable(1); fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr); attr = fnAttr.create("anchorPosition", "ancp", MFnNumericData::kDouble, 0.0); fnAttr.setKeyable(1); fnAttr.setWritable(1); fnAttr.setMin(0); fnAttr.setMax(1); fnAttr.setHidden(0); fnAttr.setStorable(1); fnAttr.setReadable(1); fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr); attr = fnAttr.create("curveLength", "cvLen", MFnNumericData::kDouble, initCurveLength); fnAttr.setKeyable(0); fnAttr.setWritable(1); fnAttr.setHidden(1); fnAttr.setStorable(1); fnAttr.setReadable(1); fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr); attr = fnAttr.create("initNormal", "norm", MFnNumericData::k3Double); fnAttr.setDefault(initNormal.x, initNormal.y, initNormal.z); fnAttr.setKeyable(0); fnAttr.setWritable(1); fnAttr.setHidden(1); fnAttr.setStorable(1); fnAttr.setReadable(1); fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr); attr = fnAttr.create("initTangent", "tang", MFnNumericData::k3Double); fnAttr.setDefault(initTangent.x, initTangent.y, initTangent.z); fnAttr.setKeyable(0); fnAttr.setWritable(1); fnAttr.setHidden(1); fnAttr.setStorable(1); fnAttr.setReadable(1); fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr); attr = fnAttr.create("jointsLength", "jsLen", MFnNumericData::kDouble, getJointsTotalLenght()); fnAttr.setKeyable(0); fnAttr.setWritable(1); fnAttr.setHidden(1); fnAttr.setStorable(1); fnAttr.setReadable(1); fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr); attr = fnAttr.create("startTwist", "strtw", MFnNumericData::kDouble, 0.0); fnAttr.setKeyable(1); fnAttr.setWritable(1); fnAttr.setHidden(0); fnAttr.setStorable(1); fnAttr.setReadable(1); fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr); attr = fnAttr.create("endTwist", "endtw", MFnNumericData::kDouble, 0.0); fnAttr.setKeyable(1); fnAttr.setWritable(1); fnAttr.setHidden(0); fnAttr.setStorable(1); fnAttr.setReadable(1); fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr); MObject twistRamp = MRampAttribute::createCurveRamp("twistRamp", "twr"); fnHandle.addAttribute(twistRamp, MFnDependencyNode::kLocalDynamicAttr); MObject scaleRamp = MRampAttribute::createCurveRamp("scaleRamp", "scr"); fnHandle.addAttribute(scaleRamp, MFnDependencyNode::kLocalDynamicAttr); } else { MPlug strPlug = fnHandle.findPlug("str"); stretchRatio = strPlug.asDouble(); } return MS::kSuccess; }
MStatus lrutils::loadGeoReference(MString geoFilePath, MString geoName, MString & name, MObject & geoObj) { MStatus status = MS::kFailure; MString projPath = MGlobal::executeCommandStringResult(MString("workspace -q -rd;"),false,false); MString relativePath = geoFilePath.substring(2,geoFilePath.numChars() - 1); //assemble the full file path of the geometry file MString fullGeoPath = projPath + relativePath; //load the geometry file as a reference into the current scene //check to see if the referenced file has already been used MStringArray refNodeList; status = MFileIO::getReferences(refNodeList, true); MyCheckStatus(status, "getReferences failed"); int numReferences = 0; for(unsigned int i = 0; i < refNodeList.length(); i++) { MString tmp = refNodeList[i]; string tmp1 = tmp.asChar(); string tmp2 = fullGeoPath.asChar(); if(std::string::npos != tmp1.find(tmp2)) numReferences++; } string str (geoFilePath.asChar()); string key ("/"); size_t found = str.rfind(key); string fileName = str.substr(found+1,str.length()-found-4); string fileNamespace; if(numReferences > 0) { stringstream tmp; tmp << fileName << (numReferences+1); fileNamespace = tmp.str(); } else { fileNamespace = fileName; } { stringstream tmp; tmp << "file -r -type \"mayaAscii\" -gl -loadReferenceDepth \"all\" -namespace \"" << fileNamespace.c_str() << "\" -options \"v=0\" \"" << fullGeoPath.asChar() << "\";"; MString referenceCommand = MString(tmp.str().c_str()); MGlobal::executeCommand(referenceCommand); } //get the referenced geometry transform node and add the metaParent //attribute to it MSelectionList selection; if(numReferences > 0) { name += (boost::lexical_cast<string>(numReferences+1)).c_str(); } stringstream geoRefName; geoRefName << fileNamespace << ":" << geoName; MString mGeoRefName = MString(geoRefName.str().c_str()); status = selection.add( mGeoRefName, true ); MyCheckStatusReturn(status, "add geoRefName "+mGeoRefName+" to selection failed."); if(selection.length() ) selection.getDependNode(0, geoObj); MFnTransform transformFn; transformFn.setObject(geoObj); MFnMessageAttribute mAttr; MObject transformAttr = mAttr.create("metaParent", "metaParent"); transformFn.addAttribute(transformAttr); if( !geoObj.isNull() ) status = MS::kSuccess; return status; }