private static List <Material> GetMaterialsMesh(ref MFnMesh Mesh, ref MDagPath Path) { // Get materials for this mesh var Result = new List <Material>(); // Fetch data var Shaders = new MObjectArray(); var ShaderIndices = new MIntArray(); Mesh.getConnectedShaders(Path.instanceNumber, Shaders, ShaderIndices); // Iterate and add for (int i = 0; i < (int)Shaders.length; i++) { // Find plug var ShaderNode = new MFnDependencyNode(Shaders[i]); var ShaderPlug = ShaderNode.findPlug("surfaceShader"); var MatPlug = new MPlugArray(); ShaderPlug.connectedTo(MatPlug, true, false); if (MatPlug.length > 0) { Result.Add(new Material(CleanNodeName(new MFnDependencyNode(MatPlug[0].node).name))); } } return(Result); }
private MFnSkinCluster getMFnSkinCluster(MFnMesh mFnMesh) { MFnSkinCluster mFnSkinCluster = null; MPlugArray connections = new MPlugArray(); mFnMesh.getConnections(connections); foreach (MPlug connection in connections) { MObject source = connection.source.node; if (source != null) { if (source.hasFn(MFn.Type.kSkinClusterFilter)) { mFnSkinCluster = new MFnSkinCluster(source); } if ((mFnSkinCluster == null) && (source.hasFn(MFn.Type.kSet) || source.hasFn(MFn.Type.kPolyNormalPerVertex))) { mFnSkinCluster = getMFnSkinCluster(source); } } } return(mFnSkinCluster); }
public static void PrintPlugs(MPlugArray plugs) { for (int i = 0; i < plugs.length; i++) { Debug.Log(i + ":" + plugs[i].name); } }
/// <summary> /// Init the list influentNodesBySkin of a skin cluster. /// By find the kjoint that are connected to the skin. /// </summary> /// <param name="skin">the skin cluster</param> /// <returns> /// The list of skin kjoint /// </returns> private List <MObject> GetInfluentNodes(MFnSkinCluster skin) { if (influentNodesBySkin.ContainsKey(skin)) { return(influentNodesBySkin[skin]); } List <MObject> influentNodes = new List <MObject>(); // Get all influenting nodes MPlugArray connections = new MPlugArray(); skin.getConnections(connections); foreach (MPlug connection in connections) { MObject source = connection.source.node; if (source != null && source.hasFn(MFn.Type.kJoint)) { if (influentNodes.Count(node => Equals(node, source)) == 0) { influentNodes.Add(source); } } } influentNodesBySkin.Add(skin, influentNodes); return(influentNodes); }
public static void RemoveUnusedTextures(MSelectionList list) { if (list == null) { Debug.Log("list null"); return; } List <MObject> deleteList = new List <MObject>(); for (int i = 0; i < list.length; i++) { MObject mo = new MObject(); list.getDependNode((uint)i, mo); MFnDependencyNode imageNode = new MFnDependencyNode(mo); MPlug texOutputPlug = imageNode.findPlug(ConstantValue.plugName_fileTexOutputColor); MPlugArray destPlugs = new MPlugArray(); texOutputPlug.destinations(destPlugs); if (destPlugs.Count == 0) { deleteList.Add(mo); Debug.Log("remove no use:" + imageNode.absoluteName); } else { Debug.Log("still used:" + imageNode.absoluteName); for (int j = 0; j < destPlugs.length; j++) { Debug.Log(" by:" + destPlugs[0].partialName(true)); } } } BasicFunc.DeleteObjects(deleteList); }
public MObject findShadingEngine(MObject node) // // Description: // Given the material MObject this method will // return the shading group that it is assigned to. // if there is no shading group associated with // the material than a null MObject is apssed back. // { MFnDependencyNode nodeFn = new MFnDependencyNode(node); MPlug srcPlug = nodeFn.findPlug("outColor"); MPlugArray nodeConnections = new MPlugArray(); srcPlug.connectedTo(nodeConnections, false, true); //loop through the connections //and find the shading engine node that //it is connected to // for (int i = 0; i < nodeConnections.length; i++) { if (nodeConnections[i].node.hasFn(MFn.Type.kShadingEngine)) { return(nodeConnections[i].node); } } //no shading engine associated so return a //null MObject // return(new MObject()); }
public static MFnDependencyNode GetPlace2dTextureForTex(MFnDependencyNode imageNode, bool createIfNotExist = true) { if (imageNode == null) { Debug.Log("image Node null"); return(null); } MPlug uvPlug = imageNode.findPlug(ConstantValue.plugName_texFileUVCoord); MPlugArray sourcePlugs = new MPlugArray(); uvPlug.connectedTo(sourcePlugs, true, false); if (sourcePlugs.length == 0) { //no input if (createIfNotExist) { MFnDependencyNode place2dTexNode = CreateShadingNode(ShadingNodeType.Utility, "place2dTexture"); MPlug p2tUVOut = place2dTexNode.findPlug(ConstantValue.plugName_place2dOutUV); string nodeName = place2dTexNode.absoluteName; MDGModifier dgModifier = new MDGModifier(); dgModifier.connect(p2tUVOut, uvPlug); dgModifier.doIt(); return(place2dTexNode); } else { return(null); } } else { return(new MFnDependencyNode(sourcePlugs[0].node)); } }
/// <summary> /// Originally written in C++ by RobTheBloke. /// See https://nccastaff.bournemouth.ac.uk/jmacey/RobTheBloke/www/research/maya/mfnmesh.htm /// </summary> /// <param name="shadingEngine"></param> /// <returns>The shader name.</returns> private static MObjectArray GetMaterials(MObject shadingEngine) { // attach a function set to the shading engine var fn = new MFnDependencyNode(shadingEngine); // get access to the surfaceShader attribute. This will be connected to // lambert , phong nodes etc. var sShader = fn.findPlug("surfaceShader"); // will hold the connections to the surfaceShader attribute var materials = new MPlugArray(); // get the material connected to the surface shader sShader.connectedTo(materials, true, false); var materialsObjects = new MObjectArray(); if (materials.Count <= 0) { return(materialsObjects); } // if we found a material foreach (var plug in materials) { materialsObjects.Add(plug.node); } return(materialsObjects); }
public maTranslator() { fBrokenConnSrcs = new MPlugArray(); fBrokenConnDests = new MPlugArray(); fDefaultNodes = new MObjectArray(); fInstanceChildren = new MDagPathArray(); fInstanceParents = new MDagPathArray(); fParentingRequired = new MDagPathArray(); }
public static MPlug getConnection(this MFnDependencyNode mFnDependencyNode, string name) { MPlugArray connections = new MPlugArray(); mFnDependencyNode.getConnections(connections); foreach (MPlug connection in connections) { if (connection.name == (mFnDependencyNode.name + "." + name)) { return(connection); } } return(null); }
public static void StuckNClothTimeWhenNotDynamic(MFnDependencyNode dn) { MPlug plug_isDynamic = dn.findPlug(ConstantValue.plugName_nCloth_isDynamic); MPlug plug_currentTime = dn.findPlug(ConstantValue.plugName_nCloth_currentTime); if (plug_isDynamic != null && plug_currentTime != null) { MPlugArray inputArr_currentTime = new MPlugArray(); plug_currentTime.connectedTo(inputArr_currentTime, true, false); MFnDependencyNode dn_time = new MFnDependencyNode(inputArr_currentTime[0].node); BindAttr.ProjectPlug(plug_isDynamic, dn_time.findPlug(ConstantValue.plugName_nClothTime_nodeState), 0, 1, (int)ConstantValue.TimeNodeState.Stuck, (int)ConstantValue.TimeNodeState.Normal); } }
public static void BindNCloth(MSelectionList selecteList = null) { if (selecteList == null) { selecteList = BasicFunc.GetSelectedList(); } int count = (int)selecteList.length; if (count <= 1) { //Debug.Log("ncloth control switch target: select [ctl,ncloth0,ncloth1...]"); return; } else { //Debug.Log("ncloth control switch target count:" + count); } MDagPath ctlDag = new MDagPath(); selecteList.getDagPath(0, ctlDag); selecteList.remove(0); MFnDependencyNode dn_ctl = new MFnDependencyNode(ctlDag.node); BasicFunc.IterateSelectedDags((dag) => { //Debug.Log("ncloth control set for:"+dag.fullPathName); MPlug ctlNewAttrPlug = BindAttr.AddBoolAttr(dn_ctl, "Dynamic_" + dag.partialPathName, true, "", false); dag.extendToShape(); MFnDependencyNode dn_nCloth = new MFnDependencyNode(dag.node); MPlug plug_isDynamic = dn_nCloth.findPlug(ConstantValue.plugName_nCloth_isDynamic); MPlug plug_currentTime = dn_nCloth.findPlug(ConstantValue.plugName_nCloth_currentTime); if (plug_isDynamic != null && plug_currentTime != null) { MPlugArray inputArr_currentTime = new MPlugArray(); plug_currentTime.connectedTo(inputArr_currentTime, true, false); MFnDependencyNode dn_time = new MFnDependencyNode(inputArr_currentTime[0].node); BindAttr.ProjectPlug(plug_isDynamic, dn_time.findPlug(ConstantValue.plugName_nClothTime_nodeState), 0, 1, (int)ConstantValue.TimeNodeState.Stuck, (int)ConstantValue.TimeNodeState.Normal); } BasicFunc.ConnectPlug(ctlNewAttrPlug, plug_isDynamic); }, MFn.Type.kNCloth, selecteList); //List<string> nclothNameList = new List<string>(); //foreach (MDagPath dag in nclothList.DagPaths()) //{ // nclothNameList.Add() //} }
void Print(MFnDependencyNode dependencyNode, int logRank, string title) { // prints RaiseVerbose(title, logRank); PrintAttributes(dependencyNode, logRank + 1); RaiseVerbose("Connections", logRank + 1); MPlugArray connections = new MPlugArray(); try { dependencyNode.getConnections(connections); RaiseVerbose("connections.Count=" + connections.Count, logRank + 2); foreach (MPlug connection in connections) { MObject source = connection.source.node; MPlugArray destinations = new MPlugArray(); connection.destinations(destinations); if (source != null && source.hasFn(MFn.Type.kDependencyNode)) { MFnDependencyNode node = new MFnDependencyNode(source); RaiseVerbose("name=" + connection.name + " partialName=" + connection.partialName(false, false, false, true) + " source=" + node.name + " source.apiType=" + source.apiType, logRank + 2); } else { RaiseVerbose("name=" + connection.name, logRank + 2); } RaiseVerbose("destinations.Count=" + destinations.Count, logRank + 3); foreach (MPlug destination in destinations) { MObject destinationObject = destination.node; if (destinationObject != null && destinationObject.hasFn(MFn.Type.kDependencyNode)) { MFnDependencyNode node = new MFnDependencyNode(destinationObject); RaiseVerbose("destination=" + node.name + " destination.apiType=" + destinationObject.apiType, logRank + 3); if (destinationObject.hasFn(MFn.Type.kShadingEngine)) { PrintAttributes(node, logRank + 4); } } } } } catch {} }
public static MSelectionList GetMaterialsWithTex(MFnDependencyNode imageNode) { MPlug plug = imageNode.findPlug(ConstantValue.plugName_fileTexOutputColor); MPlugArray destPlugs = new MPlugArray(); plug.destinations(destPlugs); //BasicFunc.PrintPlugs(destPlugs); MSelectionList newSelection = new MSelectionList(); for (int i = 0; i < destPlugs.length; i++) { newSelection.add(destPlugs[i].node); } //BasicFunc.Select(newSelection); return(newSelection); }
/// <summary> /// The MEL command only return name and not fullPathName. Unfortunatly you need the full path name to differentiate two nodes with the same names. /// /// </summary> /// <param name="skin">The skin cluster</param> /// <param name="transform">The transform above the mesh</param> /// <returns> /// The array with the node full path names. /// </returns> private MStringArray GetBoneFullPathName(MFnSkinCluster skin, MFnTransform transform) { int logRank = 3; // Get the bone names that influence the mesh // We need to keep this order as we will use an other mel command to get the weight influence MStringArray mayaInfluenceNames = new MStringArray(); MGlobal.executeCommand($"skinCluster -q -influence {transform.name}", mayaInfluenceNames); List <string> boneFullPathNames = new List <string>(); MPlugArray connections = new MPlugArray(); // Get the bone full path names of the skin cluster foreach (MObject node in GetInfluentNodes(skin)) { boneFullPathNames.Add((new MFnDagNode(node)).fullPathName); } // Change the name to the fullPathName. And check that they all share the same root node. string rootName = ""; for (int index = 0; index < mayaInfluenceNames.Count; index++) { string name = mayaInfluenceNames[index]; string name_substring = "|" + name; int indexFullPathName = boneFullPathNames.FindIndex(fullPathName => fullPathName.EndsWith(name_substring)); mayaInfluenceNames[index] = boneFullPathNames[indexFullPathName]; if (index == 0) { rootName = mayaInfluenceNames[index].Split('|')[1]; RaiseVerbose($"rootName: {rootName}", logRank + 1); } RaiseVerbose($"{index}: {name} => {mayaInfluenceNames[index]}", logRank + 1); if (!mayaInfluenceNames[index].StartsWith($"|{rootName}|") && !mayaInfluenceNames[index].Equals($"|{rootName}")) { RaiseError($"Bones don't share the same root node. {rootName} != {mayaInfluenceNames[index].Split('|')[1]}", logRank); return(null); } } return(mayaInfluenceNames); }
// The setDependentsDirty() method allows attributeAffects relationships // in a much more general way than via MPxNode::attributeAffects // which is limited to static attributes only. // The setDependentsDirty() method allows relationships to be established // between any combination of dynamic and static attributes. // // Within a setDependentsDirty() implementation you get passed in the // plug which is being set dirty, and then, based upon which plug it is, // you may choose to dirty any other plugs by adding them to the // affectedPlugs list. // // In almost all cases, the relationships you set up will be fixed for // the duration of Maya, such as "A affects B". However, you can also // set up relationships which depend upon some external factor, such // as the current frame number, the time of day, if maya was invoked in // batch mode, etc. These sorts of relationships are straightforward to // implement in your setDependentsDirty() method. // // There may also be situations where you need to look at values in the // dependency graph. It is VERY IMPORTANT that when accessing DG values // you do not cause a DG evaluation. This is because your setDependentsDirty() // method is called during dirty processing and causing an evalutaion could // put Maya into an infinite loop. The only safe way to look at values // on plugs is via the MDataBlock::outputValue() which does not trigger // an evaluation. It is recommeneded that you only look at plugs whose // values are constant or you know have already been computed. // // For this example routine, we will only implement the simplest case // of a relationship. // public override void setDependentsDirty(MPlug plugBeingDirtied, MPlugArray affectedPlugs) { MObject thisNode = thisMObject(); MFnDependencyNode fnThisNode = new MFnDependencyNode(thisNode); if (plugBeingDirtied.partialName() == "A") { // "A" is dirty, so mark "B" dirty if "B" exists. // This implements the relationship "A affects B". // MGlobal.displayInfo("affects::setDependentsDirty, \"A\" being dirtied"); MPlug pB = fnThisNode.findPlug("B"); MGlobal.displayInfo("\t\t... dirtying \"B\"\n"); affectedPlugs.append(pB); } return; }
private MFnDependencyNode getBabylonMaterialNode(MFnDependencyNode materialDependencyNode) { // Retreive connection MPlug connectionOutColor = materialDependencyNode.getConnection("outColor"); MPlugArray destinations = new MPlugArray(); connectionOutColor.destinations(destinations); // Retreive all Babylon Attributes dependency nodes List <MFnDependencyNode> babylonAttributesNodes = new List <MFnDependencyNode>(); foreach (MPlug destination in destinations) { MObject destinationObject = destination.node; if (destinationObject != null && destinationObject.hasFn(MFn.Type.kPluginHardwareShader)) { MFnDependencyNode babylonAttributesDependencyNode = new MFnDependencyNode(destinationObject); if (babylonAttributesDependencyNode.typeId.id == babylonStandardMaterialNode.id || babylonAttributesDependencyNode.typeId.id == babylonStingrayPBSMaterialNode.id || babylonAttributesDependencyNode.typeId.id == babylonAiStandardSurfaceMaterialNode.id) { babylonAttributesNodes.Add(babylonAttributesDependencyNode); } } } if (babylonAttributesNodes.Count == 0) { return(null); } else { // Occurs only if the user explicitly create a connection with several babylon attributes nodes. if (babylonAttributesNodes.Count > 1) { RaiseWarning("Babylon attributes node attached to a material should be unique. The first one is going to be used.", 2); } // Return the first shading engine node return(babylonAttributesNodes[0]); } }
private MFnSkinCluster getMFnSkinCluster(MObject mObject) { MFnSkinCluster mFnSkinCluster = null; MFnDependencyNode mFnDependencyNode = new MFnDependencyNode(mObject); MPlugArray connections = new MPlugArray(); mFnDependencyNode.getConnections(connections); for (int index = 0; index < connections.Count && mFnSkinCluster == null; index++) { MObject source = connections[index].source.node; if (source != null && source.hasFn(MFn.Type.kSkinClusterFilter)) { mFnSkinCluster = new MFnSkinCluster(source); } } return(mFnSkinCluster); }
void Print(MFnDependencyNode dependencyNode, int logRank, string title) { // prints RaiseVerbose(title, logRank); RaiseVerbose("Attributes", logRank + 1); for (uint i = 0; i < dependencyNode.attributeCount; i++) { MObject attribute = dependencyNode.attribute(i); if (attribute.hasFn(MFn.Type.kAttribute)) { MFnAttribute mFnAttribute = new MFnAttribute(attribute); RaiseVerbose("name=" + mFnAttribute.name, logRank + 2); } } RaiseVerbose("Connections", logRank + 1); MPlugArray connections = new MPlugArray(); try { dependencyNode.getConnections(connections); RaiseVerbose("connections.Count=" + connections.Count, logRank + 2); foreach (MPlug connection in connections) { MObject source = connection.source.node; if (source != null && source.hasFn(MFn.Type.kDependencyNode)) { MFnDependencyNode node = new MFnDependencyNode(source); RaiseVerbose("name=" + connection.name + " source=" + node.name, logRank + 2); } else { RaiseVerbose("name=" + connection.name, logRank + 2); } } } catch (Exception e) { } }
public static void DeleteUnusedMats(MSelectionList list) { if (list == null) { Debug.Log("list null"); return; } List <MFnDependencyNode> deleteList = new List <MFnDependencyNode>(); for (int i = 0; i < list.length; i++) { MObject mo = new MObject(); list.getDependNode((uint)i, mo); MFnDependencyNode matNode = new MFnDependencyNode(mo); MPlug plug = matNode.findPlug(ConstantValue.plugName_matColorOutput); MPlugArray plugArr = new MPlugArray(); plug.destinations(plugArr); if (plugArr.Count > 0) { MFnDependencyNode sgNode = new MFnDependencyNode(plugArr[0].node); Debug.Log(sgNode.name); MPlug plug_dagSetMemebers = sgNode.findPlug(ConstantValue.plugName_dagSetMembers); Debug.Log("numelements:" + plug_dagSetMemebers.numElements); if (plug_dagSetMemebers.numElements == 0) { deleteList.Add(matNode); deleteList.Add(sgNode); } } else { deleteList.Add(matNode); } } BasicFunc.DeleteObjects(deleteList); }
static bool CopyShaderParam(MPlug from, MPlug to, ShaderParamType spt = ShaderParamType.Color) { if (from == null || to == null) { return(false); } MPlugArray plugArr = new MPlugArray(); from.connectedTo(plugArr, true, false); if (plugArr.length == 0) { switch (spt) { case ShaderParamType.Color: { to.child(0).setFloat(from.child(0).asFloat()); to.child(1).setFloat(from.child(1).asFloat()); to.child(2).setFloat(from.child(2).asFloat()); break; } case ShaderParamType.Float: { to.setFloat(from.asFloat()); break; } } } else { MDGModifier dGModifier = new MDGModifier(); Debug.Log(from.source.partialName(true)); dGModifier.connect(from.source, to); dGModifier.doIt(); } return(true); }
public Material MakeMaterial(MFnMesh fnMesh) { MaterialGroup matGroup =new MaterialGroup () ; MObjectArray shaders =new MObjectArray() ; MIntArray indices =new MIntArray () ; fnMesh.getConnectedShaders (0, shaders, indices) ; for ( int i =0 ; i < shaders.length ; i++ ) { MFnDependencyNode shaderGroup =new MFnDependencyNode (shaders [i]) ; MPlug shaderPlug =shaderGroup.findPlug ("surfaceShader") ; MPlugArray connections =new MPlugArray () ; shaderPlug.connectedTo (connections, true, false) ; for ( int u =0 ; u < connections.length ; u++ ) { MFnDependencyNode depNode =new MFnDependencyNode (connections [u].node) ; //MPlug colorPlug =depNode.findPlug ("color") ; //MColor mcolor =new MColor () ; ///*MPlugArray cc =new MPlugArray () ; //colorPlug.connectedTo (cc, true , false) ; //if ( cc.length > 0 ) { // // Plug is driven by an input connection. // for ( int v =0 ; v < cc.length ; v++ ) { // MPlug color2Plug =cc [v] ; // Console.WriteLine (color2Plug.numChildren) ; // color2Plug.child (0).getValue (mcolor.r) ; // color2Plug.child (1).getValue (mcolor.g) ; // color2Plug.child (2).getValue (mcolor.b) ; // //color2Plug.child (3).getValue (mcolor.a) ; // } //} else {*/ // mcolor.r =colorPlug.child (0).asFloat () ; // mcolor.g =colorPlug.child (1).asFloat () ; // mcolor.b =colorPlug.child (2).asFloat () ; // //colorPlug.child (3).getValue (mcolor.a) ; ////} //MPlug trPlug =depNode.findPlug ("transparency") ; //float transparency =1.0f - trPlug.child (0).asFloat () ; ////return new DiffuseMaterial (new SolidColorBrush (Color.FromScRgb (transparency, mcolor.r, mcolor.g, mcolor.b))) ; //DiffuseMaterial diffuse =new DiffuseMaterial (new SolidColorBrush (Color.FromScRgb (transparency, mcolor.r, mcolor.g, mcolor.b))) ; //colorPlug =depNode.findPlug ("ambientColor") ; //mcolor.r =colorPlug.child (0).asFloat () ; //mcolor.g =colorPlug.child (1).asFloat () ; //mcolor.b =colorPlug.child (2).asFloat () ; //diffuse.AmbientColor =Color.FromScRgb (transparency, mcolor.r, mcolor.g, mcolor.b) ; //matGroup.Children.Add (diffuse) ; //colorPlug =depNode.findPlug ("specularColor") ; //mcolor.r =colorPlug.child (0).asFloat () ; //mcolor.g =colorPlug.child (1).asFloat () ; //mcolor.b =colorPlug.child (2).asFloat () ; //MPlug powerPlug =depNode.findPlug ("cosinePower") ; //SpecularMaterial specular =new SpecularMaterial (new SolidColorBrush (Color.FromScRgb (1.0f, mcolor.r, mcolor.g, mcolor.b)), powerPlug.asDouble ()) ; //matGroup.Children.Add (specular) ; //EmissiveMaterial emissive =new EmissiveMaterial () ; //matGroup.Children.Add (emissive) ; try { MFnLambertShader lambert =new MFnLambertShader (connections [u].node) ; SolidColorBrush brush =new SolidColorBrush (Color.FromScRgb (1.0f - lambert.transparency.r, lambert.color.r, lambert.color.g, lambert.color.b)) ; brush.Opacity =1.0f - lambert.transparency.r ; DiffuseMaterial diffuse =new DiffuseMaterial (brush) ; diffuse.AmbientColor =Color.FromScRgb (1.0f - lambert.ambientColor.a, lambert.ambientColor.r, lambert.ambientColor.g, lambert.ambientColor.b) ; // no more attributes matGroup.Children.Add (diffuse) ; // No specular color EmissiveMaterial emissive =new EmissiveMaterial (new SolidColorBrush (Color.FromScRgb (1.0f - lambert.incandescence.a, lambert.incandescence.r, lambert.incandescence.g, lambert.incandescence.b))) ; // no more attributes matGroup.Children.Add (emissive) ; } catch { } //try { // MFnReflectShader reflect =new MFnReflectShader (connections [u].node) ; // SpecularMaterial specular =new SpecularMaterial (new SolidColorBrush (Color.FromScRgb (1.0f - reflect.specularColor.a, reflect.specularColor.r, reflect.specularColor.g, reflect.specularColor.b)), reflect.cosPower) ; // // no more attributes // matGroup.Children.Add (specular) ; //} catch { //} try { MFnPhongShader phong =new MFnPhongShader (connections [u].node) ; //See Lambert //SolidColorBrush brush =new SolidColorBrush (Color.FromScRgb (1.0f - phong.transparency.r, phong.color.r, phong.color.g, phong.color.b)) ; //brush.Opacity =1.0f - phong.transparency.r ; //DiffuseMaterial diffuse =new DiffuseMaterial (brush) ; //diffuse.AmbientColor =Color.FromScRgb (1.0f - phong.ambientColor.a, phong.ambientColor.r, phong.ambientColor.g, phong.ambientColor.b) ; //// no more attributes //matGroup.Children.Add (diffuse) ; SpecularMaterial specular =new SpecularMaterial (new SolidColorBrush (Color.FromScRgb (1.0f - phong.specularColor.a, phong.specularColor.r, phong.specularColor.g, phong.specularColor.b)), phong.cosPower) ; // no more attributes matGroup.Children.Add (specular) ; //See Lambert //EmissiveMaterial emissive =new EmissiveMaterial (new SolidColorBrush (Color.FromScRgb (1.0f - phong.incandescence.a, phong.incandescence.r, phong.incandescence.g, phong.incandescence.b))) ; //// no more attributes //matGroup.Children.Add (emissive) ; } catch { } // todo //try { // MFnBlinnShader phong =new MFnBlinnShader (connections [u].node) ; // //See Lambert // //SolidColorBrush brush =new SolidColorBrush (Color.FromScRgb (1.0f - phong.transparency.r, phong.color.r, phong.color.g, phong.color.b)) ; // //brush.Opacity =1.0f - phong.transparency.r ; // //DiffuseMaterial diffuse =new DiffuseMaterial (brush) ; // //diffuse.AmbientColor = Color.FromScRgb (1.0f - phong.ambientColor.a, phong.ambientColor.r, phong.ambientColor.g, phong.ambientColor.b) ; // //// no more attributes // //matGroup.Children.Add (diffuse) ; // //See Lambert // //EmissiveMaterial emissive =new EmissiveMaterial (new SolidColorBrush (Color.FromScRgb (1.0f - phong.incandescence.a, phong.incandescence.r, phong.incandescence.g, phong.incandescence.b))) ; // //// no more attributes // //matGroup.Children.Add (emissive) ; //} catch { //} } } // Default to Blue if ( matGroup.Children.Count == 0 ) matGroup.Children.Add (new DiffuseMaterial (new SolidColorBrush (Color.FromRgb (0, 0, 255)))) ; return (matGroup) ; }
public static bool CombineSameTextures(MSelectionList list, bool deleteRepeated = true) { if (!BasicFunc.CheckSelectionList(list, 2)) { Debug.Log("please choose at least 2 materials"); return(false); } //string texFilePath = ""; //List<string> texFilePaths = new List<string>(); Dictionary <string, int> combineDic = new Dictionary <string, int>(); List <MPlug> texOutputPlugs = new List <MPlug>(); MDGModifier dGModifier = new MDGModifier(); List <MObject> deleteList = new List <MObject>(); for (int i = 0; i < list.length; i++) { MObject texObject = new MObject(); list.getDependNode((uint)i, texObject); //MImage img = new MImage(); //img.readFromTextureNode(texObject, MImage.MPixelType.kUnknown); MFnDependencyNode texDN = new MFnDependencyNode(texObject); MPlug texPlug = texDN.findPlug(ConstantValue.plugName_fileTexPath); MPlug texOutputPlug = texDN.findPlug(ConstantValue.plugName_fileTexOutputColor); //Debug.Log("texplug name:" + texPlug.name); texOutputPlugs.Add(texOutputPlug); string filePath = texPlug.asString(); //Debug.Log("path:" + filePath); if (combineDic.ContainsKey(filePath)) { //combine int targetIndex = combineDic[filePath]; //Debug.Log("combine " + i + " to " + targetIndex); MPlugArray destPlugs = new MPlugArray(); texOutputPlug.destinations(destPlugs); for (int j = 0; j < destPlugs.Count; j++) { //Debug.Log("texPlugs[targetIndex]:" + texOutputPlugs[targetIndex].name + " , destPlugs[j]" + destPlugs[j].name); dGModifier.disconnect(texOutputPlug, destPlugs[j]); dGModifier.connect(texOutputPlugs[targetIndex], destPlugs[j]); } deleteList.Add(texObject); } else { combineDic.Add(filePath, i); } } dGModifier.doIt(); if (deleteRepeated) { for (int i = 0; i < deleteList.Count; i++) { dGModifier.deleteNode(deleteList[i]); } } dGModifier.doIt(); return(true); }
public void Create(SKLFile skl) { MSelectionList currentSelection = MGlobal.activeSelectionList; MItSelectionList currentSelectionIterator = new MItSelectionList(currentSelection, MFn.Type.kMesh); MDagPath meshDagPath = new MDagPath(); if (currentSelectionIterator.isDone) { MGlobal.displayError("SKNFile:Create - No mesh selected!"); throw new Exception("SKNFile:Create - No mesh selected!"); } else { currentSelectionIterator.getDagPath(meshDagPath); currentSelectionIterator.next(); if (!currentSelectionIterator.isDone) { MGlobal.displayError("SKNFile:Create - More than one mesh selected!"); throw new Exception("SKNFile:Create - More than one mesh selected!"); } } MFnMesh mesh = new MFnMesh(meshDagPath); //Find Skin Cluster MPlug inMeshPlug = mesh.findPlug("inMesh"); MPlugArray inMeshConnections = new MPlugArray(); inMeshPlug.connectedTo(inMeshConnections, true, false); if (inMeshConnections.length == 0) { MGlobal.displayError("SKNFile:Create - Failed to find Skin Cluster!"); throw new Exception("SKNFile:Create - Failed to find Skin Cluster!"); } MPlug outputGeometryPlug = inMeshConnections[0]; MFnSkinCluster skinCluster = new MFnSkinCluster(outputGeometryPlug.node); MDagPathArray influenceDagPaths = new MDagPathArray(); uint influenceCount = skinCluster.influenceObjects(influenceDagPaths); MGlobal.displayInfo("SKNFile:Create - Influence Count: " + influenceCount); //Get SKL Influence Indices MIntArray sklInfluenceIndices = new MIntArray(influenceCount); for (int i = 0; i < influenceCount; i++) { MDagPath jointDagPath = influenceDagPaths[i]; MGlobal.displayInfo(jointDagPath.fullPathName); //Loop through Joint DAG Paths, if we find a math for the influence, write the index for (int j = 0; j < skl.JointDagPaths.Count; j++) { if (jointDagPath.equalEqual(skl.JointDagPaths[j])) { MGlobal.displayInfo("Found coresponding DAG path"); sklInfluenceIndices[i] = j; break; } } } //Add Influence indices to SKL File MIntArray maskInfluenceIndex = new MIntArray(influenceCount); for (int i = 0; i < influenceCount; i++) { maskInfluenceIndex[i] = i; skl.Influences.Add((short)sklInfluenceIndices[i]); } MObjectArray shaders = new MObjectArray(); MIntArray polygonShaderIndices = new MIntArray(); mesh.getConnectedShaders(meshDagPath.isInstanced ? meshDagPath.instanceNumber : 0, shaders, polygonShaderIndices); uint shaderCount = shaders.length; if (shaderCount > 32) //iirc 32 is the limit of how many submeshes there can be for an SKN file { MGlobal.displayError("SKNFile:Create - You've exceeded the maximum limit of 32 shaders"); throw new Exception("SKNFile:Create - You've exceeded the maximum limit of 32 shaders"); } MIntArray vertexShaders = new MIntArray(); ValidateMeshTopology(mesh, meshDagPath, polygonShaderIndices, ref vertexShaders, shaderCount); //Get Weights MFnSingleIndexedComponent vertexIndexedComponent = new MFnSingleIndexedComponent(); MObject vertexComponent = vertexIndexedComponent.create(MFn.Type.kMeshVertComponent); MIntArray groupVertexIndices = new MIntArray((uint)mesh.numVertices); for (int i = 0; i < mesh.numVertices; i++) { groupVertexIndices[i] = i; } vertexIndexedComponent.addElements(groupVertexIndices); MDoubleArray weights = new MDoubleArray(); uint weightsInfluenceCount = 0; skinCluster.getWeights(meshDagPath, vertexComponent, weights, ref weightsInfluenceCount); //Check if vertices don't have more than 4 influences and normalize weights for (int i = 0; i < mesh.numVertices; i++) { int vertexInfluenceCount = 0; double weightSum = 0; for (int j = 0; j < weightsInfluenceCount; j++) { double weight = weights[(int)(i * weightsInfluenceCount) + j]; if (weight != 0) { vertexInfluenceCount++; weightSum += weight; } } if (vertexInfluenceCount > 4) { MGlobal.displayError("SKNFile:Create - Mesh contains a vertex with more than 4 influences"); throw new Exception("SKNFile:Create - Mesh contains a vertex with more than 4 influences"); } //Normalize weights for (int j = 0; j < weightsInfluenceCount; j++) { weights[(int)(i * influenceCount) + j] /= weightSum; } } List <MIntArray> shaderVertexIndices = new List <MIntArray>(); List <List <SKNVertex> > shaderVertices = new List <List <SKNVertex> >(); List <MIntArray> shaderIndices = new List <MIntArray>(); for (int i = 0; i < shaderCount; i++) { shaderVertexIndices.Add(new MIntArray()); shaderVertices.Add(new List <SKNVertex>()); shaderIndices.Add(new MIntArray()); } MItMeshVertex meshVertexIterator = new MItMeshVertex(meshDagPath); for (meshVertexIterator.reset(); !meshVertexIterator.isDone; meshVertexIterator.next()) { int index = meshVertexIterator.index(); int shader = vertexShaders[index]; if (shader == -1) { MGlobal.displayWarning("SKNFile:Create - Mesh contains a vertex with no shader"); continue; } MPoint pointPosition = meshVertexIterator.position(MSpace.Space.kWorld); Vector3 position = new Vector3((float)pointPosition.x, (float)pointPosition.y, (float)pointPosition.z); MVectorArray normals = new MVectorArray(); MIntArray uvIndices = new MIntArray(); Vector3 normal = new Vector3(); byte[] weightIndices = new byte[4]; float[] vertexWeights = new float[4]; meshVertexIterator.getNormals(normals); //Normalize normals for (int i = 0; i < normals.length; i++) { normal.X += (float)normals[i].x; normal.Y += (float)normals[i].y; normal.Z += (float)normals[i].z; } normal.X /= normals.length; normal.Y /= normals.length; normal.Z /= normals.length; //Get Weight Influences and Weights int weightsFound = 0; for (int j = 0; j < weightsInfluenceCount && weightsFound < 4; j++) { double weight = weights[(int)(index * weightsInfluenceCount) + j]; if (weight != 0) { weightIndices[weightsFound] = (byte)maskInfluenceIndex[j]; vertexWeights[weightsFound] = (float)weight; weightsFound++; } } //Get unique UVs meshVertexIterator.getUVIndices(uvIndices); if (uvIndices.length != 0) { List <int> seen = new List <int>(); for (int j = 0; j < uvIndices.length; j++) { int uvIndex = uvIndices[j]; if (!seen.Contains(uvIndex)) { seen.Add(uvIndex); float u = 0; float v = 0; mesh.getUV(uvIndex, ref u, ref v); SKNVertex vertex = new SKNVertex(position, weightIndices, vertexWeights, normal, new Vector2(u, 1 - v)); vertex.UVIndex = uvIndex; shaderVertices[shader].Add(vertex); shaderVertexIndices[shader].append(index); } } } else { MGlobal.displayError("SKNFile:Create - Mesh contains a vertex with no UVs"); throw new Exception("SKNFile:Create - Mesh contains a vertex with no UVs"); } } //Convert from Maya indices to data indices int currentIndex = 0; MIntArray dataIndices = new MIntArray((uint)mesh.numVertices, -1); for (int i = 0; i < shaderCount; i++) { for (int j = 0; j < shaderVertexIndices[i].length; j++) { int index = shaderVertexIndices[i][j]; if (dataIndices[index] == -1) { dataIndices[index] = currentIndex; shaderVertices[i][j].DataIndex = currentIndex; } else { shaderVertices[i][j].DataIndex = dataIndices[index]; } currentIndex++; } this.Vertices.AddRange(shaderVertices[i]); } MItMeshPolygon polygonIterator = new MItMeshPolygon(meshDagPath); for (polygonIterator.reset(); !polygonIterator.isDone; polygonIterator.next()) { int polygonIndex = (int)polygonIterator.index(); int shaderIndex = polygonShaderIndices[polygonIndex]; MIntArray indices = new MIntArray(); MPointArray points = new MPointArray(); polygonIterator.getTriangles(points, indices); if (polygonIterator.hasUVsProperty) { MIntArray vertices = new MIntArray(); MIntArray newIndices = new MIntArray(indices.length, -1); polygonIterator.getVertices(vertices); for (int i = 0; i < vertices.length; i++) { int dataIndex = dataIndices[vertices[i]]; int uvIndex; polygonIterator.getUVIndex(i, out uvIndex); if (dataIndex == -1 || dataIndex >= this.Vertices.Count) { MGlobal.displayError("SKNFIle:Create - Data Index outside of range"); throw new Exception("SKNFIle:Create - Data Index outside of range"); } for (int j = dataIndex; j < this.Vertices.Count; j++) { if (this.Vertices[j].DataIndex != dataIndex) { MGlobal.displayError("SKNFIle:Create - Can't find corresponding face vertex in data"); throw new Exception("SKNFIle:Create - Can't find corresponding face vertex in data"); } else if (this.Vertices[j].UVIndex == uvIndex) { for (int k = 0; k < indices.length; k++) { if (indices[k] == vertices[i]) { newIndices[k] = j; } } break; } } } for (int i = 0; i < newIndices.length; i++) { shaderIndices[shaderIndex].append(newIndices[i]); } } else { for (int i = 0; i < indices.length; i++) { shaderIndices[shaderIndex].append(dataIndices[indices[i]]); } } } uint startIndex = 0; uint startVertex = 0; for (int i = 0; i < shaderCount; i++) { MPlug shaderPlug = new MFnDependencyNode(shaders[i]).findPlug("surfaceShader"); MPlugArray plugArray = new MPlugArray(); shaderPlug.connectedTo(plugArray, true, false); string name = new MFnDependencyNode(plugArray[0].node).name; uint indexCount = shaderIndices[i].length; uint vertexCount = shaderVertexIndices[i].length; //Copy indices to SKLFile for (int j = 0; j < indexCount; j++) { this.Indices.Add((ushort)shaderIndices[i][j]); } this.Submeshes.Add(new SKNSubmesh(name, startVertex, vertexCount, startIndex, indexCount)); startIndex += indexCount; startVertex += vertexCount; } MGlobal.displayInfo("SKNFile:Create - Created SKN File"); }
public override void doIt(MArgList args) { // parse the command arguments // parseArgs(args); uint count = 0; // if the character flag was used, create the clip on the specified // character, otherwise, create a character // MFnCharacter fnCharacter = new MFnCharacter(); if (fCharacter.isNull) { MSelectionList activeList = new MSelectionList(); MGlobal.getActiveSelectionList(activeList); if (0 == activeList.length) { throw new ApplicationException("Empty Active Selection List."); } // create a character using the selection list // fCharacter = fnCharacter.create(activeList, MFnSet.Restriction.kNone); } else fnCharacter.setObject(fCharacter); // Get the array of members of the character. We will create a clip // for them. // MPlugArray plugs = new MPlugArray(); fnCharacter.getMemberPlugs(plugs); // Now create a animCurves to use as a clip for the character. // The curves will be set up between frames 0 and 10; // MTime start = new MTime(0.0); MTime duration = new MTime(10.0); MObjectArray clipCurves = new MObjectArray(); for (count = 0; count < plugs.length; ++count) { // Now create a bunch of animCurves to use as a clip for the // character // MFnAnimCurve fnCurve = new MFnAnimCurve(); MObject curve = fnCurve.create(MFnAnimCurve.AnimCurveType.kAnimCurveTL); // plugType); fnCurve.addKeyframe(start, 5.0); fnCurve.addKeyframe(duration, 15.0); clipCurves.append(curve); } // Create a source clip node and add the animation to it // MFnClip fnClipCreate = new MFnClip(); MObject sourceClip = fnClipCreate.createSourceClip(start, duration, fMod); fnCharacter.attachSourceToCharacter(sourceClip, fMod); for (count = 0; count < plugs.length; ++count) { MPlug animPlug = plugs[(int)count]; fnCharacter.addCurveToClip(clipCurves[(int)count], sourceClip, animPlug, fMod); } // instance the clip // MTime schedStart = new MTime(15.0); MObject instancedClip = fnClipCreate.createInstancedClip(sourceClip, schedStart, fMod); fnCharacter.attachInstanceToCharacter(instancedClip, fMod); // instance the clip a second time, at time 30 // schedStart.value = 30.0; MObject instancedClip2 = fnClipCreate.createInstancedClip(sourceClip, schedStart, fMod); fnCharacter.attachInstanceToCharacter(instancedClip2, fMod); return; }
public void Load(string name, SKLFile skl = null) { MIntArray polygonIndexCounts = new MIntArray((uint)this.Indices.Count / 3); MIntArray polygonIndices = new MIntArray((uint)this.Indices.Count); MFloatPointArray vertices = new MFloatPointArray((uint)this.Vertices.Count); MFloatArray arrayU = new MFloatArray((uint)this.Vertices.Count); MFloatArray arrayV = new MFloatArray((uint)this.Vertices.Count); MVectorArray normals = new MVectorArray((uint)this.Vertices.Count); MIntArray normalIndices = new MIntArray((uint)this.Vertices.Count); MFnMesh mesh = new MFnMesh(); MDagPath meshDagPath = new MDagPath(); MDGModifier modifier = new MDGModifier(); MFnSet set = new MFnSet(); for (int i = 0; i < this.Indices.Count / 3; i++) { polygonIndexCounts[i] = 3; } for (int i = 0; i < this.Indices.Count; i++) { polygonIndices[i] = this.Indices[i]; } for (int i = 0; i < this.Vertices.Count; i++) { SKNVertex vertex = this.Vertices[i]; vertices[i] = new MFloatPoint(vertex.Position.X, vertex.Position.Y, vertex.Position.Z); arrayU[i] = vertex.UV.X; arrayV[i] = 1 - vertex.UV.Y; normals[i] = new MVector(vertex.Normal.X, vertex.Normal.Y, vertex.Normal.Z); normalIndices[i] = i; } //Assign mesh data mesh.create(this.Vertices.Count, this.Indices.Count / 3, vertices, polygonIndexCounts, polygonIndices, arrayU, arrayV, MObject.kNullObj); mesh.setVertexNormals(normals, normalIndices); mesh.getPath(meshDagPath); mesh.assignUVs(polygonIndexCounts, polygonIndices); //Set names mesh.setName(name); MFnTransform transformNode = new MFnTransform(mesh.parent(0)); transformNode.setName("transform_" + name); //Get render partition MGlobal.displayInfo("SKNFile:Load - Searching for Render Partition"); MItDependencyNodes itDependencyNodes = new MItDependencyNodes(MFn.Type.kPartition); MFnPartition renderPartition = new MFnPartition(); bool foundRenderPartition = false; for (; !itDependencyNodes.isDone; itDependencyNodes.next()) { renderPartition.setObject(itDependencyNodes.thisNode); MGlobal.displayInfo("SKNFile:Load - Iterating through partition: " + renderPartition.name + " IsRenderPartition: " + renderPartition.isRenderPartition); if (renderPartition.name == "renderPartition" && renderPartition.isRenderPartition) { MGlobal.displayInfo("SKNFile:Load - Found render partition"); foundRenderPartition = true; break; } } //Create Materials for (int i = 0; i < this.Submeshes.Count; i++) { MFnDependencyNode dependencyNode = new MFnDependencyNode(); MFnLambertShader lambertShader = new MFnLambertShader(); SKNSubmesh submesh = this.Submeshes[i]; MObject shader = lambertShader.create(true); lambertShader.setName(submesh.Name); lambertShader.color = MaterialProvider.GetMayaColor(i); MObject shadingEngine = dependencyNode.create("shadingEngine", submesh.Name + "_SG"); MObject materialInfo = dependencyNode.create("materialInfo", submesh.Name + "_MaterialInfo"); if (foundRenderPartition) { MPlug partitionPlug = new MFnDependencyNode(shadingEngine).findPlug("partition"); MPlug setsPlug = MayaHelper.FindFirstNotConnectedElement(renderPartition.findPlug("sets")); modifier.connect(partitionPlug, setsPlug); } else { MGlobal.displayInfo("SKNFile:Load - Couldn't find Render Partition for mesh: " + name + "." + submesh.Name); } MPlug outColorPlug = lambertShader.findPlug("outColor"); MPlug surfaceShaderPlug = new MFnDependencyNode(shadingEngine).findPlug("surfaceShader"); modifier.connect(outColorPlug, surfaceShaderPlug); MPlug messagePlug = new MFnDependencyNode(shadingEngine).findPlug("message"); MPlug shadingGroupPlug = new MFnDependencyNode(materialInfo).findPlug("shadingGroup"); modifier.connect(messagePlug, shadingGroupPlug); modifier.doIt(); MFnSingleIndexedComponent component = new MFnSingleIndexedComponent(); MObject faceComponent = component.create(MFn.Type.kMeshPolygonComponent); MIntArray groupPolygonIndices = new MIntArray(); uint endIndex = (submesh.StartIndex + submesh.IndexCount) / 3; for (uint j = submesh.StartIndex / 3; j < endIndex; j++) { groupPolygonIndices.append((int)j); } component.addElements(groupPolygonIndices); set.setObject(shadingEngine); set.addMember(meshDagPath, faceComponent); } if (skl == null) { mesh.updateSurface(); } else { MFnSkinCluster skinCluster = new MFnSkinCluster(); MSelectionList jointPathsSelectionList = new MSelectionList(); jointPathsSelectionList.add(meshDagPath); for (int i = 0; i < skl.Influences.Count; i++) { short jointIndex = skl.Influences[i]; SKLJoint joint = skl.Joints[jointIndex]; jointPathsSelectionList.add(skl.JointDagPaths[jointIndex]); MGlobal.displayInfo(string.Format("SKNFile:Load:Bind - Added joint [{0}] {1} to binding selection", joint.ID, joint.Name)); } MGlobal.selectCommand(jointPathsSelectionList); MGlobal.executeCommand("skinCluster -mi 4 -tsb -n skinCluster_" + name); MPlug inMeshPlug = mesh.findPlug("inMesh"); MPlugArray inMeshConnections = new MPlugArray(); inMeshPlug.connectedTo(inMeshConnections, true, false); if (inMeshConnections.length == 0) { MGlobal.displayError("SKNFile:Load:Bind - Failed to find the created Skin Cluster"); throw new Exception("SKNFile:Load:Bind - Failed to find the created Skin Cluster"); } MPlug outputGeometryPlug = inMeshConnections[0]; MDagPathArray influencesDagPaths = new MDagPathArray(); skinCluster.setObject(outputGeometryPlug.node); skinCluster.influenceObjects(influencesDagPaths); MIntArray influenceIndices = new MIntArray((uint)skl.Influences.Count); for (int i = 0; i < skl.Influences.Count; i++) { MDagPath influencePath = skl.JointDagPaths[skl.Influences[i]]; for (int j = 0; j < skl.Influences.Count; j++) { if (influencesDagPaths[j].partialPathName == influencePath.partialPathName) { influenceIndices[i] = j; MGlobal.displayInfo("SKNReader:Load:Bind - Added Influence Joint: " + i + " -> " + j); break; } } } MFnSingleIndexedComponent singleIndexedComponent = new MFnSingleIndexedComponent(); MObject vertexComponent = singleIndexedComponent.create(MFn.Type.kMeshVertComponent); MIntArray groupVertexIndices = new MIntArray((uint)this.Vertices.Count); for (int i = 0; i < this.Vertices.Count; i++) { groupVertexIndices[i] = i; } singleIndexedComponent.addElements(groupVertexIndices); MGlobal.executeCommand(string.Format("setAttr {0}.normalizeWeights 0", skinCluster.name)); MDoubleArray weights = new MDoubleArray((uint)(this.Vertices.Count * skl.Influences.Count)); for (int i = 0; i < this.Vertices.Count; i++) { SKNVertex vertex = this.Vertices[i]; for (int j = 0; j < 4; j++) { double weight = vertex.Weights[j]; int influence = vertex.BoneIndices[j]; if (weight != 0) { weights[(i * skl.Influences.Count) + influence] = weight; } } } skinCluster.setWeights(meshDagPath, vertexComponent, influenceIndices, weights, false); MGlobal.executeCommand(string.Format("setAttr {0}.normalizeWeights 1", skinCluster.name)); MGlobal.executeCommand(string.Format("skinPercent -normalize true {0} {1}", skinCluster.name, mesh.name)); mesh.updateSurface(); } }
// // Description: // Given the material MObject this method will // return the shading group that it is assigned to. // if there is no shading group associated with // the material than a null MObject is apssed back. // public MObject findShadingEngine(MObject node) { MFnDependencyNode nodeFn = new MFnDependencyNode(node); MPlug srcPlug = nodeFn.findPlug("outColor"); MPlugArray nodeConnections = new MPlugArray(); srcPlug.connectedTo(nodeConnections, false, true); //loop through the connections //and find the shading engine node that //it is connected to // for(int i = 0; i < nodeConnections.length; i++) { if(nodeConnections[i].node.hasFn(MFn.Type.kShadingEngine)) return nodeConnections[i].node; } //no shading engine associated so return a //null MObject // return new MObject(); }
public override void doIt(MArgList args) { MSelectionList list = new MSelectionList(); if ( args.length > 0 ) { // Arg list is > 0 so use objects that were passes in // uint last = args.length; for ( uint i = 0; i < last; i++ ) { // Attempt to find all of the objects matched // by the string and add them to the list // string argStr = args.asString(i); list.add(argStr); } } else { // Get arguments from Maya's selection list. MGlobal.getActiveSelectionList(list); } MObject node = new MObject(); MObjectArray nodePath = new MObjectArray(); MFnDependencyNode nodeFn = new MFnDependencyNode(); MFnDependencyNode dgNodeFnSet = new MFnDependencyNode(); for (MItSelectionList iter = new MItSelectionList(list); !iter.isDone; iter.next()) { iter.getDependNode(node); // // The following code shows how to navigate the DG manually without // using an iterator. First, find the attribute that you are // interested. Then connect a plug to it and see where the plug // connected to. Once you get all the connections, you can choose // which route you want to go. // // In here, we wanted to get to the nodes that instObjGroups connected // to since we know that the shadingEngine connects to the instObjGroup // attribute. // nodeFn.setObject( node ); MObject iogAttr = null; try { iogAttr = nodeFn.attribute("instObjGroups"); } catch (Exception) { MGlobal.displayInfo(nodeFn.name + ": is not a renderable object, skipping"); continue; } MPlug iogPlug = new MPlug(node, iogAttr); MPlugArray iogConnections = new MPlugArray(); // // instObjGroups is a multi attribute. In this example, just the // first connection will be tried. // if (!iogPlug.elementByLogicalIndex(0).connectedTo(iogConnections, false, true)) { MGlobal.displayInfo(nodeFn.name + ": is not in a shading group, skipping"); continue; } // // Now we would like to traverse the DG starting from the shadingEngine // since most likely all file texture nodes will be found. Note the // filter used to initialize the DG iterator. There are lots of filter // type available in MF.Type that you can choose to suite your needs. // bool foundATexture = false; for ( int i=0; i < iogConnections.length; i++ ) { MObject currentNode = iogConnections[i].node; // // Note that upon initialization, the current pointer of the // iterator already points to the first valid node. // MItDependencyGraph dgIt = new MItDependencyGraph(currentNode, MFn.Type.kFileTexture, MItDependencyGraph.Direction.kUpstream, MItDependencyGraph.Traversal.kBreadthFirst, MItDependencyGraph.Level.kNodeLevel); if (dgIt == null) { continue; } dgIt.disablePruningOnFilter(); for ( ; !dgIt.isDone; dgIt.next() ) { MObject thisNode = dgIt.thisNode(); dgNodeFnSet.setObject(thisNode); try { dgIt.getNodePath(nodePath); } catch (Exception) { MGlobal.displayInfo("getNodePath"); continue; } // // append the starting node. // nodePath.append(node); dumpInfo( thisNode, dgNodeFnSet, nodePath ); foundATexture = true; } } if ( !foundATexture ) { MGlobal.displayInfo(nodeFn.name + ": is not connected to a file texture"); } } return; }
public override bool shouldBeUsedFor(MObject sourceNode, MObject destinationNode, MPlug sourcePlug, MPlug destinationPlug) { bool result = false; if(sourceNode.hasFn(MFn.Type.kLambert)) { //if the source node was a lambert //than we will check the downstream connections to see //if a slope shader is assigned to it. // MObject shaderNode = new MObject(); MFnDependencyNode src = new MFnDependencyNode(sourceNode); MPlugArray connections = new MPlugArray(); src.getConnections(connections); for(int i = 0; i < connections.length; i++) { //check the incoming connections to this plug // MPlugArray connectedPlugs = new MPlugArray(); connections[i].connectedTo(connectedPlugs, true, false); for(int j = 0; j < connectedPlugs.length; j++) { //if the incoming node is a slope shader than //set shaderNode equal to it and break out of the inner //loop // if(new MFnDependencyNode(connectedPlugs[j].node).typeName == "slopeShaderNodeCSharp") { shaderNode = connectedPlugs[j].node; break; } } //if the shaderNode is not null //than we have found a slopeShaderNodeCSharp // if(!shaderNode.isNull) { //if the destination node is a mesh than we will take //care of this connection so set the result to true //and break out of the outer loop // if(destinationNode.hasFn(MFn.Type.kMesh)) result = true; break; } } } if (new MFnDependencyNode(sourceNode).typeName == "slopeShaderNodeCSharp") //if the sourceNode is a slope shader than check what we //are dropping on to // { if(destinationNode.hasFn(MFn.Type.kLambert)) result = true; else if (destinationNode.hasFn(MFn.Type.kMesh)) result = true; } return result; }
public static StaticObject Create() { MDagPath meshDagPath = new MDagPath(); MItSelectionList selectionIterator = MayaHelper.GetActiveSelectionListIterator(MFn.Type.kMesh); selectionIterator.getDagPath(meshDagPath); MFnMesh mesh = new MFnMesh(meshDagPath); selectionIterator.next(); if (!selectionIterator.isDone) { MGlobal.displayError("StaticObject:Create - More than 1 mesh is selected"); throw new Exception("StaticObject:Create - More than 1 mesh is selected"); } if (!mesh.IsTriangulated()) { MGlobal.displayError("StaticObject:Create - Mesh isn't triangulated"); throw new Exception("StaticObject:Create - Mesh isn't triangulated"); } if (mesh.ContainsHoles()) { MGlobal.displayError("StaticObject:Create - Mesh Contains holes"); throw new Exception("StaticObject:Create - Mesh Contains holes"); } MayaMeshData meshData = mesh.GetMeshData(); Dictionary <int, string> shaderNames = new Dictionary <int, string>(); List <StaticObjectFace> faces = new List <StaticObjectFace>(); //Build Shader Name map for (int i = 0; i < meshData.ShaderIndices.Count; i++) { int shaderIndex = meshData.ShaderIndices[i]; if (!shaderNames.ContainsKey(shaderIndex)) { MPlug shaderPlug = new MFnDependencyNode(meshData.Shaders[shaderIndex]).findPlug("surfaceShader"); MPlugArray plugArray = new MPlugArray(); shaderPlug.connectedTo(plugArray, true, false); MFnDependencyNode material = new MFnDependencyNode(shaderPlug[0].node); shaderNames.Add(shaderIndex, material.name); } } //Construct faces int currentIndex = 0; for (int polygonIndex = 0; polygonIndex < mesh.numPolygons; polygonIndex++) { int shaderIndex = meshData.ShaderIndices[polygonIndex]; uint[] faceIndices = { (uint)meshData.TriangleVertices[currentIndex], (uint)meshData.TriangleVertices[currentIndex + 1], (uint)meshData.TriangleVertices[currentIndex + 2] }; Vector2[] uvs = { new Vector2(meshData.UArray[currentIndex], 1 - meshData.VArray[currentIndex]), new Vector2(meshData.UArray[currentIndex + 1], 1 - meshData.VArray[currentIndex + 1]), new Vector2(meshData.UArray[currentIndex + 2], 1 - meshData.VArray[currentIndex + 2]) }; faces.Add(new StaticObjectFace(faceIndices, shaderNames[shaderIndex], uvs)); currentIndex += 3; } return(new StaticObject(CreateSubmeshes(meshData.VertexArray.ToVector3List(), new List <ColorRGBA4B>(), faces))); }
// // Description: // Overloaded function from MPxDragAndDropBehavior // this method will handle the connection between the slopeShaderNodeCSharp and the shader it is // assigned to as well as any meshes that it is assigned to. // public override void connectNodeToNode(MObject sourceNode, MObject destinationNode, bool force) { MFnDependencyNode src = new MFnDependencyNode(sourceNode); //if we are dragging from a lambert //we want to check what we are dragging //onto. if(sourceNode.hasFn(MFn.Type.kLambert)) { //MObject shaderNode; MPlugArray connections = new MPlugArray(); MObjectArray shaderNodes = new MObjectArray(); shaderNodes.clear(); //if the source node was a lambert //than we will check the downstream connections to see //if a slope shader is assigned to it. // src.getConnections(connections); int i; for(i = 0; i < connections.length; i++) { //check the incoming connections to this plug // MPlugArray connectedPlugs = new MPlugArray(); connections[i].connectedTo(connectedPlugs, true, false); for(uint j = 0; j < connectedPlugs.length; j++) { //if the incoming node is a slope shader than //append the node to the shaderNodes array // MObject currentnode = connectedPlugs[i].node; if (new MFnDependencyNode(currentnode).typeName == "slopeShaderNodeCSharp") { shaderNodes.append(currentnode); } } } //if we found a shading node //than check the destination node //type to see if it is a mesh // if(shaderNodes.length > 0) { MFnDependencyNode dest = new MFnDependencyNode(destinationNode); if(destinationNode.hasFn(MFn.Type.kMesh)) { //if the node is a mesh than for each slopeShaderNodeCSharp //connect the worldMesh attribute to the dirtyShaderPlug //attribute to force an evaluation of the node when the mesh //changes // for(i = 0; i < shaderNodes.length; i++) { MPlug srcPlug = dest.findPlug("worldMesh"); MPlug destPlug = new MFnDependencyNode(shaderNodes[i]).findPlug("dirtyShaderPlug"); if(!srcPlug.isNull && !destPlug.isNull) { string cmd = "connectAttr -na "; cmd += srcPlug.name + " "; cmd += destPlug.name; try { // in slopeShaderBehavior.cpp, this may excute failed but continue on the following code, so we catch it. MGlobal.executeCommand(cmd); } catch (System.Exception) { MGlobal.displayError("ExcuteCommand (" + cmd + ") failed."); } } } //get the shading engine so we can assign the shader //to the mesh after doing the connection // MObject shadingEngine = findShadingEngine(sourceNode); //if there is a valid shading engine than make //the connection // if(!shadingEngine.isNull) { string cmd = "sets -edit -forceElement "; cmd += new MFnDependencyNode(shadingEngine).name + " "; cmd += new MFnDagNode(destinationNode).partialPathName; MGlobal.executeCommand(cmd); } } } } else if (src.typeName == "slopeShaderNodeCSharp") //if we are dragging from a slope shader //than we want to see what we are dragging onto // { if(destinationNode.hasFn(MFn.Type.kMesh)) { //if the user is dragging onto a mesh //than make the connection from the worldMesh //to the dirtyShader plug on the slopeShaderNodeCSharp // MFnDependencyNode dest = new MFnDependencyNode(destinationNode); MPlug srcPlug = dest.findPlug("worldMesh"); MPlug destPlug = src.findPlug("dirtyShaderPlug"); if(!srcPlug.isNull && !destPlug.isNull) { string cmd = "connectAttr -na "; cmd += srcPlug.name + " "; cmd += destPlug.name; MGlobal.executeCommand(cmd); } } } return; }
public override void doIt(MArgList args) { MSelectionList list = new MSelectionList(); if (args.length > 0) { // Arg list is > 0 so use objects that were passes in // uint last = args.length; for (uint i = 0; i < last; i++) { // Attempt to find all of the objects matched // by the string and add them to the list // string argStr = args.asString(i); list.add(argStr); } } else { // Get arguments from Maya's selection list. MGlobal.getActiveSelectionList(list); } MObject node = new MObject(); MObjectArray nodePath = new MObjectArray(); MFnDependencyNode nodeFn = new MFnDependencyNode(); MFnDependencyNode dgNodeFnSet = new MFnDependencyNode(); for (MItSelectionList iter = new MItSelectionList(list); !iter.isDone; iter.next()) { iter.getDependNode(node); // // The following code shows how to navigate the DG manually without // using an iterator. First, find the attribute that you are // interested. Then connect a plug to it and see where the plug // connected to. Once you get all the connections, you can choose // which route you want to go. // // In here, we wanted to get to the nodes that instObjGroups connected // to since we know that the shadingEngine connects to the instObjGroup // attribute. // nodeFn.setObject(node); MObject iogAttr = null; try { iogAttr = nodeFn.attribute("instObjGroups"); } catch (Exception) { MGlobal.displayInfo(nodeFn.name + ": is not a renderable object, skipping"); continue; } MPlug iogPlug = new MPlug(node, iogAttr); MPlugArray iogConnections = new MPlugArray(); // // instObjGroups is a multi attribute. In this example, just the // first connection will be tried. // if (!iogPlug.elementByLogicalIndex(0).connectedTo(iogConnections, false, true)) { MGlobal.displayInfo(nodeFn.name + ": is not in a shading group, skipping"); continue; } // // Now we would like to traverse the DG starting from the shadingEngine // since most likely all file texture nodes will be found. Note the // filter used to initialize the DG iterator. There are lots of filter // type available in MF.Type that you can choose to suite your needs. // bool foundATexture = false; for (int i = 0; i < iogConnections.length; i++) { MObject currentNode = iogConnections[i].node; // // Note that upon initialization, the current pointer of the // iterator already points to the first valid node. // MItDependencyGraph dgIt = new MItDependencyGraph(currentNode, MFn.Type.kFileTexture, MItDependencyGraph.Direction.kUpstream, MItDependencyGraph.Traversal.kBreadthFirst, MItDependencyGraph.Level.kNodeLevel); if (dgIt == null) { continue; } dgIt.disablePruningOnFilter(); for ( ; !dgIt.isDone; dgIt.next()) { MObject thisNode = dgIt.thisNode(); dgNodeFnSet.setObject(thisNode); try { dgIt.getNodePath(nodePath); } catch (Exception) { MGlobal.displayInfo("getNodePath"); continue; } // // append the starting node. // nodePath.append(node); dumpInfo(thisNode, dgNodeFnSet, nodePath); foundATexture = true; } } if (!foundATexture) { MGlobal.displayInfo(nodeFn.name + ": is not connected to a file texture"); } } return; }
public override void setDependentsDirty(MPlug plug, MPlugArray plugArray) // // Description // // Horribly abuse the purpose of this method to notify the Viewport 2.0 // renderer that something about this shape has changed and that it should // be retranslated. // { // if the dirty attribute is the output mesh then we need to signal the // the renderer that it needs to update the object if ( plug.attribute.equalEqual(inputSurface) ) { MRenderer.setGeometryDrawDirty(thisMObject()); } return; }
public override void doIt(MArgList args) { MArgDatabase argData; MPxCommandSyntaxFlagAttribute MyAttribute = (MPxCommandSyntaxFlagAttribute)Attribute.GetCustomAttribute(typeof(NodeInfoCmd), typeof(MPxCommandSyntaxFlagAttribute)); MSyntax syntax = new MSyntax(); if (MyAttribute != null) { syntax.addFlag(MyAttribute.ShortFlag, MyAttribute.LongFlag); } else { syntax.addFlag(kQuietFlag, kQuietFlagLong); } try { argData = new MArgDatabase(syntax, args); } catch (System.Exception ex) { MGlobal.displayInfo(ex.Message); } MSelectionList selectList = MGlobal.activeSelectionList; foreach (MObject node in selectList.DependNodes()) { MFnDependencyNode depFn = new MFnDependencyNode(); depFn.setObject(node); string nodename = depFn.name; nodename +=":"; printType(node, nodename); MPlugArray connectedPlugs = new MPlugArray(); try { depFn.getConnections(connectedPlugs); } catch (System.Exception ex) { MGlobal.displayInfo(ex.Message); } uint numberOfPlugs = connectedPlugs.length; string msgFmt = MStringResource.getString(NodeInfoCmd.rConnFound); MGlobal.displayInfo( String.Format(msgFmt, Convert.ToString(numberOfPlugs)) ); string pInfoMsg = MStringResource.getString(NodeInfoCmd.rPlugInfo); for (int i = 0; i < numberOfPlugs; i++ ) { MPlug plug = connectedPlugs[i]; string pInfo = plug.info; MGlobal.displayInfo(pInfoMsg+pInfo); MPlugArray array = new MPlugArray(); plug.connectedTo(array, true, false); string dInfoMsg = MStringResource.getString(rPlugDestOf); for (int j = 0; j < array.length; j++ ) { MObject mnode = array[j].node; printType(mnode, dInfoMsg); } } } return; }
public override void doIt(MArgList args) { // parse the command arguments // parseArgs(args); uint count = 0; // if the character flag was used, create the clip on the specified // character, otherwise, create a character // MFnCharacter fnCharacter = new MFnCharacter(); if (fCharacter.isNull) { MSelectionList activeList = new MSelectionList(); MGlobal.getActiveSelectionList(activeList); if (0 == activeList.length) { throw new ApplicationException("Empty Active Selection List."); } // create a character using the selection list // fCharacter = fnCharacter.create(activeList, MFnSet.Restriction.kNone); } else { fnCharacter.setObject(fCharacter); } // Get the array of members of the character. We will create a clip // for them. // MPlugArray plugs = new MPlugArray(); fnCharacter.getMemberPlugs(plugs); // Now create a animCurves to use as a clip for the character. // The curves will be set up between frames 0 and 10; // MTime start = new MTime(0.0); MTime duration = new MTime(10.0); MObjectArray clipCurves = new MObjectArray(); for (count = 0; count < plugs.length; ++count) { // Now create a bunch of animCurves to use as a clip for the // character // MFnAnimCurve fnCurve = new MFnAnimCurve(); MObject curve = fnCurve.create(MFnAnimCurve.AnimCurveType.kAnimCurveTL); // plugType); fnCurve.addKeyframe(start, 5.0); fnCurve.addKeyframe(duration, 15.0); clipCurves.append(curve); } // Create a source clip node and add the animation to it // MFnClip fnClipCreate = new MFnClip(); MObject sourceClip = fnClipCreate.createSourceClip(start, duration, fMod); fnCharacter.attachSourceToCharacter(sourceClip, fMod); for (count = 0; count < plugs.length; ++count) { MPlug animPlug = plugs[(int)count]; fnCharacter.addCurveToClip(clipCurves[(int)count], sourceClip, animPlug, fMod); } // instance the clip // MTime schedStart = new MTime(15.0); MObject instancedClip = fnClipCreate.createInstancedClip(sourceClip, schedStart, fMod); fnCharacter.attachInstanceToCharacter(instancedClip, fMod); // instance the clip a second time, at time 30 // schedStart.value = 30.0; MObject instancedClip2 = fnClipCreate.createInstancedClip(sourceClip, schedStart, fMod); fnCharacter.attachInstanceToCharacter(instancedClip2, fMod); return; }
public static void ConvertToRSMaterial(MFnDependencyNode matNode, bool deleteOrigin) { //replace output to shadingEngine MPlug plug_matColorOutput = matNode.findPlug(ConstantValue.plugName_matColorOutput); MPlugArray plugArr_matColorOutDest = new MPlugArray(); plug_matColorOutput.destinations(plugArr_matColorOutDest); //get textures MPlug plug_matColorInput = matNode.findPlug(ConstantValue.plugName_matColorInput); MPlug plug_matTransparency = matNode.findPlug(ConstantValue.plugName_matTransparency); MFnDependencyNode rsArchiNode = CreateShadingNode(ShadingNodeType.Shader, ConstantValue.nodeName_RS_Architectural); if (matNode.name.StartsWith("mat_")) { rsArchiNode.setName("rs" + matNode.name); } else { rsArchiNode.setName("rsmat_" + matNode.name); } MPlug plug_rsArchiDiffuse = rsArchiNode.findPlug(ConstantValue.plugName_RS_diffuse); MPlug plug_rsArchiTransColor = rsArchiNode.findPlug(ConstantValue.plugName_RS_transColor); MPlug plug_rsArchiTransWeight = rsArchiNode.findPlug(ConstantValue.plugName_RS_transWeight); MPlug plug_rsArchiOutColor = rsArchiNode.findPlug(ConstantValue.plugName_RS_outColor); MDGModifier dGModifier = new MDGModifier(); for (int i = 0; i < plugArr_matColorOutDest.length; i++) { dGModifier.disconnect(plug_matColorOutput, plugArr_matColorOutDest[i]); dGModifier.connect(plug_rsArchiOutColor, plugArr_matColorOutDest[i]); } CopyShaderParam(plug_matColorInput, plug_rsArchiDiffuse); //if (plug_matColorInput.source == null) //{ // plug_rsArchiDiffuse.child(0).setFloat(plug_matColorInput.child(0).asFloat()); // plug_rsArchiDiffuse.child(1).setFloat(plug_matColorInput.child(1).asFloat()); // plug_rsArchiDiffuse.child(2).setFloat(plug_matColorInput.child(2).asFloat()); //} //else //{ // dGModifier.connect(plug_matColorInput.source, plug_rsArchiDiffuse); //} CopyShaderParam(plug_matTransparency, plug_rsArchiTransColor); if (plug_matTransparency.child(0).asFloat() == 0 && plug_matTransparency.child(1).asFloat() == 0 && plug_matTransparency.child(2).asFloat() == 0) { plug_rsArchiTransWeight.setFloat(1); } else { plug_rsArchiTransWeight.setFloat(0); } //if (plug_matTransparency.source == null) //{ // //plug_rsArchiTransColor.setValue(plug_matColorInput.asMObject()); // float matTransparency = plug_matTransparency.asFloat(); // if (matTransparency == 0) // { // plug_rsArchiTransWeight.setFloat(0); // plug_rsArchiTransColor.child(0).setFloat(0); // plug_rsArchiTransColor.child(1).setFloat(0); // plug_rsArchiTransColor.child(2).setFloat(0); // } // else // { // plug_rsArchiTransWeight.setFloat(1); // plug_rsArchiTransColor.child(0).setFloat(plug_matTransparency.child(0).asFloat()); // plug_rsArchiTransColor.child(1).setFloat(plug_matTransparency.child(1).asFloat()); // plug_rsArchiTransColor.child(2).setFloat(plug_matTransparency.child(2).asFloat()); // } //} //else //{ // dGModifier.connect(plug_matTransparency.source, plug_rsArchiTransColor); // plug_rsArchiTransWeight.setFloat(1); //} if (deleteOrigin) { dGModifier.deleteNode(matNode.objectProperty); } dGModifier.doIt(); }
// // Write the 'connectAttr' commands for all of a node's incoming // connections. // protected void writeNodeConnections(FileStream f, MObject node) { MFnDependencyNode nodeFn = new MFnDependencyNode(node); MPlugArray plugs = new MPlugArray(); try { nodeFn.getConnections(plugs); } catch (Exception) { } uint numBrokenConns = fBrokenConnSrcs.length; uint numPlugs = plugs.length; int i; string result = ""; for (i = 0; i < numPlugs; i++) { // // We only care about connections where we are the destination. // MPlug destPlug = plugs[i]; MPlugArray srcPlug = new MPlugArray(); destPlug.connectedTo(srcPlug, true, false); if (srcPlug.length > 0) { MObject srcNode = srcPlug[0].node; MFnDependencyNode srcNodeFn = new MFnDependencyNode(srcNode); // // Don't write the connection if the source is not writable... // if (!srcNodeFn.canBeWritten) continue; // // or the connection was made in a referenced file... // if (destPlug.isFromReferencedFile) continue; // // or the plug is procedural... // if (destPlug.isProcedural) continue; // // or it is a connection between a default node and a shared // node (because those will get set up automatically). // if (srcNodeFn.isDefaultNode && nodeFn.isShared) continue; result += "connectAttr \""; // // Default nodes get a colon at the start of their names. // if (srcNodeFn.isDefaultNode) result += ":"; result += (srcPlug[0].partialName(true) + "\" \""); if (nodeFn.isDefaultNode) result += ":"; result += (destPlug.partialName(true) + "\""); // // If the src plug is also one from which a broken // connection originated, then add the "-rd/referenceDest" flag // to the command. That will help Maya to better adjust if the // referenced file has changed the next time it is loaded. // if (srcNodeFn.isFromReferencedFile) { int j; for (j = 0; j < numBrokenConns; j++) { if (fBrokenConnSrcs[j] == srcPlug[0]) { result += (" -rd \"" + fBrokenConnDests[j].partialName(true) + "\""); break; } } } // // If the plug is locked, then add a "-l/lock" flag to the // command. // if (destPlug.isLocked) result += " -l on"; // // If the destination attribute is a multi for which index // does not matter, then we must add the "-na/nextAvailable" // flag to the command. // MObject attr = destPlug.attribute; MFnAttribute attrFn = new MFnAttribute(attr); if (!attrFn.indexMatters) result += " -na"; result += (";" + "\n"); } } writeString(f, result); }
/// <summary> /// Get TRS and visiblity animations of the transform /// </summary> /// <param name="transform">Transform above mesh/camera/light</param> /// <returns></returns> private List <BabylonAnimation> GetAnimation(MFnTransform transform) { // Animations MPlugArray connections = new MPlugArray(); MStringArray animCurvList = new MStringArray(); MIntArray keysTime = new MIntArray(); MDoubleArray keysValue = new MDoubleArray(); MFloatArray translateValues = new MFloatArray(); MFloatArray rotateValues = new MFloatArray(); MFloatArray scaleValues = new MFloatArray(); MFloatArray visibilityValues = new MFloatArray(); MFloatArray keyTimes = new MFloatArray(); List <BabylonAnimationKey> keys = new List <BabylonAnimationKey>(); List <BabylonAnimation> animationsObject = new List <BabylonAnimation>(); //Get the animCurve MGlobal.executeCommand("listConnections -type \"animCurve\" " + transform.fullPathName + ";", animCurvList); List <AnimCurvData> animCurvesData = new List <AnimCurvData>(); foreach (String animCurv in animCurvList) { AnimCurvData animCurvData = new AnimCurvData(); animCurvesData.Add(animCurvData); animCurvData.animCurv = animCurv; //Get the key time for each curves MGlobal.executeCommand("keyframe -q " + animCurv + ";", keysTime); //Get the value for each curves MGlobal.executeCommand("keyframe - q -vc -absolute " + animCurv + ";", keysValue); if (animCurv.EndsWith("translateZ") || animCurv.EndsWith("rotateX") || animCurv.EndsWith("rotateY")) { for (int index = 0; index < keysTime.Count; index++) { // Switch coordinate system at object level animCurvData.valuePerFrame.Add(keysTime[index], (float)keysValue[index] * -1.0f); } } else { for (int index = 0; index < keysTime.Count; index++) { animCurvData.valuePerFrame.Add(keysTime[index], (float)keysValue[index]); } } } string[] mayaAnimationProperties = new string[] { "translate", "rotate", "scale" }; string[] babylonAnimationProperties = new string[] { "position", "rotationQuaternion", "scaling" }; string[] axis = new string[] { "X", "Y", "Z" }; // Init TRS default values Dictionary <string, float> defaultValues = new Dictionary <string, float>(); float[] position = null; float[] rotationQuaternion = null; float[] rotation = null; float[] scaling = null; GetTransform(transform, ref position, ref rotationQuaternion, ref rotation, ref scaling); // coordinate system already switched defaultValues.Add("translateX", position[0]); defaultValues.Add("translateY", position[1]); defaultValues.Add("translateZ", position[2]); defaultValues.Add("rotateX", rotation[0]); defaultValues.Add("rotateY", rotation[1]); defaultValues.Add("rotateZ", rotation[2]); defaultValues.Add("scaleX", scaling[0]); defaultValues.Add("scaleY", scaling[1]); defaultValues.Add("scaleZ", scaling[2]); for (int indexAnimationProperty = 0; indexAnimationProperty < mayaAnimationProperties.Length; indexAnimationProperty++) { string mayaAnimationProperty = mayaAnimationProperties[indexAnimationProperty]; // Retreive animation curves data for current animation property // Ex: all "translate" data are "translateX", "translateY", "translateZ" List <AnimCurvData> animDataProperty = animCurvesData.Where(data => data.animCurv.Contains(mayaAnimationProperty)).ToList(); if (animDataProperty.Count == 0) { // Property is not animated continue; } // Get all frames for this property List <int> framesProperty = new List <int>(); foreach (var animData in animDataProperty) { framesProperty.AddRange(animData.valuePerFrame.Keys); } framesProperty = framesProperty.Distinct().ToList(); framesProperty.Sort(); // Get default values for this property BabylonAnimationKey lastBabylonAnimationKey = new BabylonAnimationKey(); lastBabylonAnimationKey.frame = 0; lastBabylonAnimationKey.values = new float[] { defaultValues[mayaAnimationProperty + "X"], defaultValues[mayaAnimationProperty + "Y"], defaultValues[mayaAnimationProperty + "Z"] }; // Compute all values for this property List <BabylonAnimationKey> babylonAnimationKeys = new List <BabylonAnimationKey>(); foreach (var frameProperty in framesProperty) { BabylonAnimationKey babylonAnimationKey = new BabylonAnimationKey(); babylonAnimationKeys.Add(babylonAnimationKey); // Frame babylonAnimationKey.frame = frameProperty; // Values float[] valuesProperty = new float[3]; for (int indexAxis = 0; indexAxis < axis.Length; indexAxis++) { AnimCurvData animCurvDataAxis = animDataProperty.Find(data => data.animCurv.EndsWith(axis[indexAxis])); float value; if (animCurvDataAxis != null && animCurvDataAxis.valuePerFrame.ContainsKey(frameProperty)) { value = animCurvDataAxis.valuePerFrame[frameProperty]; } else { value = lastBabylonAnimationKey.values[indexAxis]; } valuesProperty[indexAxis] = value; } babylonAnimationKey.values = valuesProperty.ToArray(); // Update last known values lastBabylonAnimationKey = babylonAnimationKey; } // Convert euler to quaternion angles if (indexAnimationProperty == 1) // Rotation { foreach (var babylonAnimationKey in babylonAnimationKeys) { BabylonVector3 eulerAngles = BabylonVector3.FromArray(babylonAnimationKey.values); BabylonQuaternion quaternionAngles = eulerAngles.toQuaternion(); babylonAnimationKey.values = quaternionAngles.ToArray(); } } var keysFull = new List <BabylonAnimationKey>(babylonAnimationKeys); // Optimization OptimizeAnimations(babylonAnimationKeys, true); // Ensure animation has at least 2 frames if (IsAnimationKeysRelevant(keys)) { // Create BabylonAnimation string babylonAnimationProperty = babylonAnimationProperties[indexAnimationProperty]; animationsObject.Add(new BabylonAnimation() { dataType = indexAnimationProperty == 1 ? (int)BabylonAnimation.DataType.Quaternion : (int)BabylonAnimation.DataType.Vector3, name = babylonAnimationProperty + " animation", framePerSecond = 30, loopBehavior = (int)BabylonAnimation.LoopBehavior.Cycle, property = babylonAnimationProperty, keys = babylonAnimationKeys.ToArray(), keysFull = keysFull }); } } return(animationsObject); }
/// <summary> /// /// </summary> /// <param name="mDagPath">DAG path to the transform above camera</param> /// <param name="babylonScene"></param> /// <returns></returns> private BabylonNode ExportCamera(MDagPath mDagPath, BabylonScene babylonScene) { RaiseMessage(mDagPath.partialPathName, 1); // Transform above camera MFnTransform mFnTransform = new MFnTransform(mDagPath); // Camera direct child of the transform MFnCamera mFnCamera = null; for (uint i = 0; i < mFnTransform.childCount; i++) { MObject childObject = mFnTransform.child(i); if (childObject.apiType == MFn.Type.kCamera) { var _mFnCamera = new MFnCamera(childObject); if (!_mFnCamera.isIntermediateObject) { mFnCamera = _mFnCamera; } } } if (mFnCamera == null) { RaiseError("No camera found has child of " + mDagPath.fullPathName); return(null); } // --- prints --- #region prints RaiseVerbose("BabylonExporter.Camera | mFnCamera data", 2); RaiseVerbose("BabylonExporter.Camera | mFnCamera.eyePoint(MSpace.Space.kWorld).toString()=" + mFnCamera.eyePoint(MSpace.Space.kTransform).toString(), 3); RaiseVerbose("BabylonExporter.Camera | mFnCamera.viewDirection(MSpace.Space.kWorld).toString()=" + mFnCamera.viewDirection(MSpace.Space.kTransform).toString(), 3); RaiseVerbose("BabylonExporter.Camera | mFnCamera.upDirection(MSpace.Space.kWorld).toString()=" + mFnCamera.upDirection(MSpace.Space.kTransform).toString(), 3); RaiseVerbose("BabylonExporter.Camera | mFnCamera.rightDirection(MSpace.Space.kWorld).toString()=" + mFnCamera.rightDirection(MSpace.Space.kTransform).toString(), 3); RaiseVerbose("BabylonExporter.Camera | mFnCamera.centerOfInterestPoint(MSpace.Space.kWorld).toString()=" + mFnCamera.centerOfInterestPoint(MSpace.Space.kTransform).toString(), 3); RaiseVerbose("BabylonExporter.Camera | mFnCamera.centerOfInterest=" + mFnCamera.centerOfInterest, 3); RaiseVerbose("BabylonExporter.Camera | mFnCamera.aspectRatio=" + mFnCamera.aspectRatio, 3); RaiseVerbose("BabylonExporter.Camera | mFnCamera.horizontalFieldOfView=" + mFnCamera.horizontalFieldOfView, 3); RaiseVerbose("BabylonExporter.Camera | mFnCamera.verticalFieldOfView=" + mFnCamera.verticalFieldOfView, 3); RaiseVerbose("BabylonExporter.Camera | mFnCamera.horizontalFieldOfView / mFnCamera.verticalFieldOfView=" + mFnCamera.horizontalFieldOfView / mFnCamera.verticalFieldOfView, 3); RaiseVerbose("BabylonExporter.Camera | mFnCamera.focalLength=" + mFnCamera.focalLength, 3); RaiseVerbose("BabylonExporter.Camera | mFnCamera.nearFocusDistance=" + mFnCamera.nearFocusDistance, 3); RaiseVerbose("BabylonExporter.Camera | mFnCamera.nearClippingPlane=" + mFnCamera.nearClippingPlane, 3); RaiseVerbose("BabylonExporter.Camera | mFnCamera.unnormalizedNearClippingPlane=" + mFnCamera.unnormalizedNearClippingPlane, 3); RaiseVerbose("BabylonExporter.Camera | mFnCamera.farFocusDistance=" + mFnCamera.farFocusDistance, 3); RaiseVerbose("BabylonExporter.Camera | mFnCamera.farClippingPlane=" + mFnCamera.farClippingPlane, 3); RaiseVerbose("BabylonExporter.Camera | mFnCamera.unnormalizedFarClippingPlane=" + mFnCamera.unnormalizedFarClippingPlane, 3); RaiseVerbose("BabylonExporter.Camera | mFnCamera.isClippingPlanes=" + mFnCamera.isClippingPlanes, 3); RaiseVerbose("BabylonExporter.Camera | mFnCamera.isIntermediateObject=" + mFnCamera.isIntermediateObject, 3); RaiseVerbose("BabylonExporter.Camera | mFnCamera.focusDistance=" + mFnCamera.focusDistance, 3); RaiseVerbose("BabylonExporter.Camera | mFnCamera.isStereo=" + mFnCamera.isStereo, 3); RaiseVerbose("BabylonExporter.Camera | mFnCamera.eyeOffset=" + mFnCamera.eyeOffset, 3); RaiseVerbose("BabylonExporter.Camera | mFnCamera.shutterAngle=" + mFnCamera.shutterAngle, 3); RaiseVerbose("BabylonExporter.Camera | mFnCamera.isDepthOfField=" + mFnCamera.isDepthOfField, 3); RaiseVerbose("BabylonExporter.Camera | mFnCamera.renderPanZoom=" + mFnCamera.renderPanZoom, 3); Print(mFnTransform, 2, "Print ExportCamera mFnTransform"); Print(mFnCamera, 2, "Print ExportCamera mFnCamera"); #endregion if (IsCameraExportable(mFnCamera, mDagPath) == false) { return(null); } var babylonCamera = new BabylonCamera { name = mFnTransform.name, id = mFnTransform.uuid().asString() }; // Hierarchy ExportHierarchy(babylonCamera, mFnTransform); // Position / rotation RaiseVerbose("BabylonExporter.Camera | ExportTransform", 2); float[] position = null; float[] rotationQuaternion = null; float[] rotation = null; float[] scaling = null; GetTransform(mFnTransform, ref position, ref rotationQuaternion, ref rotation, ref scaling); babylonCamera.position = position; if (_exportQuaternionsInsteadOfEulers) { babylonCamera.rotationQuaternion = rotationQuaternion; } babylonCamera.rotation = rotation; // Field of view of babylon is the vertical one babylonCamera.fov = (float)mFnCamera.verticalFieldOfView; // Clipping planes babylonCamera.minZ = (float)mFnCamera.nearClippingPlane; babylonCamera.maxZ = (float)mFnCamera.farClippingPlane; // Constraints on near clipping plane if (babylonCamera.minZ == 0.0f) { babylonCamera.minZ = 0.1f; } // TODO - Retreive from Maya //// Type //babylonCamera.type = cameraNode.MaxNode.GetStringProperty("babylonjs_type", "FreeCamera"); //// Control //babylonCamera.speed = cameraNode.MaxNode.GetFloatProperty("babylonjs_speed", 1.0f); //babylonCamera.inertia = cameraNode.MaxNode.GetFloatProperty("babylonjs_inertia", 0.9f); //// Collisions //babylonCamera.checkCollisions = cameraNode.MaxNode.GetBoolProperty("babylonjs_checkcollisions"); //babylonCamera.applyGravity = cameraNode.MaxNode.GetBoolProperty("babylonjs_applygravity"); //babylonCamera.ellipsoid = cameraNode.MaxNode.GetVector3Property("babylonjs_ellipsoid"); // Target MFnTransform target = null; MObject cameraGroupObject = mFnCamera.findPlug("centerOfInterest").source.node; if (cameraGroupObject.apiType == MFn.Type.kLookAt) { MFnDependencyNode cameraGroup = new MFnDependencyNode(cameraGroupObject); // Retreive the camera aim transform MPlugArray connections = new MPlugArray(); cameraGroup.getConnections(connections); foreach (MPlug connection in connections) { if (connection.name.EndsWith("targetParentMatrix")) // ugly { MObject connectionSourceObject = connection.source.node; target = new MFnTransform(connectionSourceObject); break; } } } if (target != null) { babylonCamera.lockedTargetId = target.uuid().asString(); } //// TODO - Check if should be local or world //var vDir = new MVector(0, 0, -1); //var transformationMatrix = new MTransformationMatrix(mFnTransform.transformationMatrix); //vDir *= transformationMatrix.asMatrix(1); //vDir = vDir.Add(position); //babylonCamera.target = new[] { vDir.X, vDir.Y, vDir.Z }; // Animations if (target == null) { ExportNodeAnimation(babylonCamera, mFnTransform); } else { ExportNodeAnimationFrameByFrame(babylonCamera, mFnTransform); } babylonScene.CamerasList.Add(babylonCamera); RaiseMessage("BabylonExporter.Camera | done", 2); return(babylonCamera); }
/// <summary> /// Convert the Maya texture animation of a MFnDependencyNode in Babylon animations /// </summary> /// <param name="textureDependencyNode">The MFnDependencyNode of the texture</param> /// <returns>A list of texture animation</returns> public List <BabylonAnimation> GetTextureAnimations(MFnDependencyNode textureDependencyNode) { List <BabylonAnimation> animations = new List <BabylonAnimation>(); // Look for a "place2dTexture" object in the connections of the node. // The "place2dTexture" object contains the animation parameters MPlugArray connections = new MPlugArray(); textureDependencyNode.getConnections(connections); int index = 0; string place2dTexture = null; while (index < connections.Count && place2dTexture == null) { MPlug connection = connections[index]; MObject source = connection.source.node; if (source != null && source.hasFn(MFn.Type.kPlace2dTexture)) { MFnDependencyNode node = new MFnDependencyNode(source); place2dTexture = node.name; } index++; } if (place2dTexture != null) { IDictionary <string, string> properties = new Dictionary <string, string> { ["offsetU"] = "uOffset", ["offsetU"] = "uOffset", ["offsetV"] = "vOffset", ["repeatU"] = "uScale", ["repeatV"] = "vScale" }; // Get the animation for each properties for (index = 0; index < properties.Count; index++) { KeyValuePair <string, string> property = properties.ElementAt(index); BabylonAnimation animation = GetAnimationFloat(place2dTexture, property.Key, property.Value); if (animation != null) { animations.Add(animation); } } // For the rotation, convert degree to radian BabylonAnimation rotationAnimation = GetAnimationFloat(place2dTexture, "rotateFrame", "wAng"); if (rotationAnimation != null) { BabylonAnimationKey[] keys = rotationAnimation.keys; for (index = 0; index < keys.Length; index++) { var key = keys[index]; key.values[0] *= (float)(Math.PI / 180d); } animations.Add(rotationAnimation); } } return(animations); }
// // Description // // Horribly abuse the purpose of this method to notify the Viewport 2.0 // renderer that something about this shape has changed and that it should // be retranslated. // public override void setDependentsDirty(MPlug plug, MPlugArray plugArray) { // if the dirty attribute is the output mesh then we need to signal the // the renderer that it needs to update the object if ( plug.attribute.equalEqual(inputSurface) ) { MRenderer.setGeometryDrawDirty(thisMObject()); } return; }
public MObject findShadingEngine(MObject node) // // Description: // Given the material MObject this method will // return the shading group that it is assigned to. // if there is no shading group associated with // the material than a null MObject is apssed back. // { MFnDependencyNode nodeFn = new MFnDependencyNode(node); MPlug srcPlug = nodeFn.findPlug("outColor"); MPlugArray nodeConnections = new MPlugArray(); srcPlug.connectedTo(nodeConnections, false, true); //loop through the connections //and find the shading engine node that //it is connected to // for(int i = 0; i < nodeConnections.length; i++) { if(nodeConnections[i].node.hasFn(MFn.Type.kShadingEngine)) return nodeConnections[i].node; } //no shading engine associated so return a //null MObject // return new MObject(); }