public MSelectionList RestoreSelectionOnList(MSelectionList targetList = null, bool selectResult = false) { if (targetList == null || targetList.length == 0) { targetList = BasicFunc.GetSelectedList(); } MSelectionList resultSelection = new MSelectionList(); for (int i = 0; i < targetList.length; i++) { if (i >= selectedIndicesList.Count) { break; } MDagPath dag = new MDagPath(); targetList.getDagPath((uint)i, dag); MFnSingleIndexedComponent sic = new MFnSingleIndexedComponent(); MObject components = sic.create(MFn.Type.kMeshPolygonComponent); sic.addElements(new MIntArray(selectedIndicesList[i])); resultSelection.add(dag, components); //resultSelection.add(dag); } if (selectResult) { BasicFunc.Select(resultSelection); } return(resultSelection); }
public MSelectionList RestoreSelectionOnDag(MDagPath targetDag = null, bool selectResult = false) { if (targetDag == null) { return(null); } MSelectionList resultSelection = new MSelectionList(); MFnSingleIndexedComponent sic = new MFnSingleIndexedComponent(); MObject components = sic.create(MFn.Type.kMeshPolygonComponent); sic.addElements(new MIntArray(selectedIndicesList[0])); resultSelection.add(targetDag, components); //resultSelection.add(targetDag); if (selectResult) { BasicFunc.Select(resultSelection); } return(resultSelection); }
// // Description: // // Component/attribute matching method. // This method validates component names and indices which are // specified as a string and adds the corresponding component // to the passed in selection list. // // For instance, select commands such as "select shape1.vtx[0:7]" // are validated with this method and the corresponding component // is added to the selection list. // // Arguments // // item - DAG selection item for the object being matched // spec - attribute specification object // list - list to add components to // // Returns // // the result of the match // public override MatchResult matchComponent(MSelectionList item, MAttributeSpecArray spec, MSelectionList list) { MatchResult result = MatchResult.kMatchOk; MAttributeSpec attrSpec = spec[0]; int dim = attrSpec.dimensions; // Look for attributes specifications of the form : // vtx[ index ] // vtx[ lower:upper ] // if ( (1 == spec.length) && (dim > 0) && (attrSpec.name == "vtx") ) { int numVertices = (int)meshGeom().vertices.length; MAttributeIndex attrIndex = attrSpec[0]; int upper = 0; int lower = 0; if ( attrIndex.hasLowerBound ) { attrIndex.getLower( out lower ); } if ( attrIndex.hasUpperBound ) { attrIndex.getUpper( out upper ); } // Check the attribute index range is valid // if ( (lower > upper) || (upper >= numVertices) ) { result = MatchResult.kMatchInvalidAttributeRange; } else { MDagPath path = new MDagPath(); item.getDagPath( 0, path ); MFnSingleIndexedComponent fnVtxComp = new MFnSingleIndexedComponent(); MObject vtxComp = fnVtxComp.create( MFn.Type.kMeshVertComponent ); for ( int i=lower; i<=upper; i++ ) { fnVtxComp.addElement( i ); } list.add( path, vtxComp ); } } else { // Pass this to the parent class return base.matchComponent( item, spec, list ); } return result; }
// // Description // This method is used by Maya when it needs to create a component // containing every vertex (or control point) in the shape. // This will get called if you apply some deformer to the whole // shape, i.e. select the shape in object mode and add a deformer to it. // // Returns // // A "complete" component representing all vertices in the shape. // // Support deformers (components) // public override MObject createFullVertexGroup() { // Create a vertex component // MFnSingleIndexedComponent fnComponent = new MFnSingleIndexedComponent(); MObject fullComponent = fnComponent.create( MFn.Type.kMeshVertComponent ); // Set the component to be complete, i.e. the elements in // the component will be [0:numVertices-1] // int numVertices = (int)meshGeom().vertices.length; fnComponent.setCompleteData( numVertices ); return fullComponent; }
public void Load(string name) { List <StaticObjectVertex> vertices = GetVertices(); List <uint> indices = GetIndices(); MIntArray polygonIndexCounts = new MIntArray((uint)indices.Count / 3); MIntArray polygonIndices = new MIntArray((uint)indices.Count); MFloatPointArray meshVertices = new MFloatPointArray((uint)vertices.Count); MFloatArray arrayU = new MFloatArray((uint)vertices.Count); MFloatArray arrayV = new MFloatArray((uint)vertices.Count); MFnMesh mesh = new MFnMesh(); MDagPath meshDagPath = new MDagPath(); MDGModifier modifier = new MDGModifier(); MFnSet set = new MFnSet(); for (int i = 0; i < indices.Count / 3; i++) { polygonIndexCounts[i] = 3; } for (int i = 0; i < indices.Count; i++) { polygonIndices[i] = (int)indices[i]; } for (int i = 0; i < vertices.Count; i++) { StaticObjectVertex vertex = vertices[i]; meshVertices[i] = new MFloatPoint(vertex.Position.X, vertex.Position.Y, vertex.Position.Z); arrayU[i] = vertex.UV.X; arrayV[i] = 1 - vertex.UV.Y; } //Assign mesh data mesh.create(vertices.Count, indices.Count / 3, meshVertices, polygonIndexCounts, polygonIndices, arrayU, arrayV, MObject.kNullObj); 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 MFnPartition renderPartition = MayaHelper.FindRenderPartition(); //Create Materials uint startIndex = 0; for (int i = 0; i < this.Submeshes.Count; i++) { MFnDependencyNode dependencyNode = new MFnDependencyNode(); MFnLambertShader lambertShader = new MFnLambertShader(); StaticObjectSubmesh submesh = this.Submeshes[i]; 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"); MPlug partitionPlug = new MFnDependencyNode(shadingEngine).findPlug("partition"); MPlug setsPlug = MayaHelper.FindFirstNotConnectedElement(renderPartition.findPlug("sets")); modifier.connect(partitionPlug, setsPlug); 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 = (startIndex + (uint)submesh.Indices.Count) / 3; for (uint j = startIndex / 3; j < endIndex; j++) { groupPolygonIndices.append((int)j); } component.addElements(groupPolygonIndices); set.setObject(shadingEngine); set.addMember(meshDagPath, faceComponent); startIndex += (uint)submesh.Indices.Count; } mesh.updateSurface(); }
// Support deformers (components) // public override MObject createFullVertexGroup() // // Description // This method is used by Maya when it needs to create a component // containing every vertex (or control point) in the shape. // This will get called if you apply some deformer to the whole // shape, i.e. select the shape in object mode and add a deformer to it. // // Returns // // A "complete" component representing all vertices in the shape. // { // Create a vertex component // MFnSingleIndexedComponent fnComponent = new MFnSingleIndexedComponent(); MObject fullComponent = fnComponent.create( MFn.Type.kMeshVertComponent ); // Set the component to be complete, i.e. the elements in // the component will be [0:numVertices-1] // int numVertices = (int)meshGeom().vertices.length; fnComponent.setCompleteData( numVertices ); return fullComponent; }
public override MatchResult matchComponent(MSelectionList item, MAttributeSpecArray spec, MSelectionList list) // // Description: // // Component/attribute matching method. // This method validates component names and indices which are // specified as a string and adds the corresponding component // to the passed in selection list. // // For instance, select commands such as "select shape1.vtx[0:7]" // are validated with this method and the corresponding component // is added to the selection list. // // Arguments // // item - DAG selection item for the object being matched // spec - attribute specification object // list - list to add components to // // Returns // // the result of the match // { MatchResult result = MatchResult.kMatchOk; MAttributeSpec attrSpec = spec[0]; int dim = attrSpec.dimensions; // Look for attributes specifications of the form : // vtx[ index ] // vtx[ lower:upper ] // if ( (1 == spec.length) && (dim > 0) && (attrSpec.name == "vtx") ) { int numVertices = (int)meshGeom().vertices.length; MAttributeIndex attrIndex = attrSpec[0]; int upper = 0; int lower = 0; if ( attrIndex.hasLowerBound ) { attrIndex.getLower( out lower ); } if ( attrIndex.hasUpperBound ) { attrIndex.getUpper( out upper ); } // Check the attribute index range is valid // if ( (lower > upper) || (upper >= numVertices) ) { result = MatchResult.kMatchInvalidAttributeRange; } else { MDagPath path = new MDagPath(); item.getDagPath( 0, path ); MFnSingleIndexedComponent fnVtxComp = new MFnSingleIndexedComponent(); MObject vtxComp = fnVtxComp.create( MFn.Type.kMeshVertComponent ); for ( int i=lower; i<=upper; i++ ) { fnVtxComp.addElement( i ); } list.add( path, vtxComp ); } } else { // Pass this to the parent class return base.matchComponent( item, spec, list ); } return result; }
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(); } }
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"); }
// // Description: // // Vertex selection. // // Arguments: // // selectInfo - the selection state information // selectionList - the list of selected items to add to // worldSpaceSelectPts - // public bool selectVertices( MSelectInfo selectInfo, MSelectionList selectionList, MPointArray worldSpaceSelectPts) { bool selected = false; M3dView view = selectInfo.view; MPoint xformedPoint = new MPoint(); MPoint selectionPoint = new MPoint(); double z = 0.0; double previousZ = 0.0; int closestPointVertexIndex = -1; MDagPath path = selectInfo.multiPath; // Create a component that will store the selected vertices // MFnSingleIndexedComponent fnComponent = new MFnSingleIndexedComponent(); MObject surfaceComponent = fnComponent.create( MFn.Type.kMeshVertComponent ); uint vertexIndex; // if the user did a single mouse click and we find > 1 selection // we will use the alignmentMatrix to find out which is the closest // MMatrix alignmentMatrix = new MMatrix(); MPoint singlePoint = new MPoint(); bool singleSelection = selectInfo.singleSelection; if( singleSelection ) { alignmentMatrix = selectInfo.alignmentMatrix; } // Get the geometry information // apiMesh meshNode = (apiMesh)surfaceShape; apiMeshGeom geom = meshNode.meshGeom(); // Loop through all vertices of the mesh and // see if they lie withing the selection area // uint numVertices = geom.vertices.length; for ( vertexIndex=0; vertexIndex<numVertices; vertexIndex++ ) { MPoint currentPoint = geom.vertices[ (int)vertexIndex ]; // Sets OpenGL's render mode to select and stores // selected items in a pick buffer // view.beginSelect(); OpenGL.glBegin(OpenGL.GL_POINTS); OpenGL.glVertex3f((float)currentPoint[0], (float)currentPoint[1], (float)currentPoint[2] ); OpenGL.glEnd(); if ( view.endSelect() > 0 ) // Hit count > 0 { selected = true; if ( singleSelection ) { xformedPoint = currentPoint; xformedPoint.homogenize(); xformedPoint.multiplyEqual( alignmentMatrix ); z = xformedPoint.z; if ( closestPointVertexIndex < 0 || z > previousZ ) { closestPointVertexIndex = (int)vertexIndex; singlePoint = currentPoint; previousZ = z; } } else { // multiple selection, store all elements // fnComponent.addElement( (int)vertexIndex ); } } } // If single selection, insert the closest point into the array // if ( selected && selectInfo.singleSelection ) { fnComponent.addElement(closestPointVertexIndex); // need to get world space position for this vertex // selectionPoint = singlePoint; selectionPoint.multiplyEqual( path.inclusiveMatrix ); } // Add the selected component to the selection list // if ( selected ) { MSelectionList selectionItem = new MSelectionList(); selectionItem.add( path, surfaceComponent ); MSelectionMask mask = new MSelectionMask( MSelectionMask.SelectionType.kSelectComponentsMask ); selectInfo.addSelection( selectionItem, selectionPoint, selectionList, worldSpaceSelectPts, mask, true ); } return selected; }
public bool selectVertices(MSelectInfo selectInfo, MSelectionList selectionList, MPointArray worldSpaceSelectPts) // // Description: // // Vertex selection. // // Arguments: // // selectInfo - the selection state information // selectionList - the list of selected items to add to // worldSpaceSelectPts - // { bool selected = false; M3dView view = selectInfo.view; MPoint xformedPoint = new MPoint(); MPoint selectionPoint = new MPoint(); double z = 0.0; double previousZ = 0.0; int closestPointVertexIndex = -1; MDagPath path = selectInfo.multiPath; // Create a component that will store the selected vertices // MFnSingleIndexedComponent fnComponent = new MFnSingleIndexedComponent(); MObject surfaceComponent = fnComponent.create(MFn.Type.kMeshVertComponent); uint vertexIndex; // if the user did a single mouse click and we find > 1 selection // we will use the alignmentMatrix to find out which is the closest // MMatrix alignmentMatrix = new MMatrix(); MPoint singlePoint = new MPoint(); bool singleSelection = selectInfo.singleSelection; if (singleSelection) { alignmentMatrix = selectInfo.alignmentMatrix; } // Get the geometry information // apiMesh meshNode = (apiMesh)surfaceShape; apiMeshGeom geom = meshNode.meshGeom(); // Loop through all vertices of the mesh and // see if they lie withing the selection area // uint numVertices = geom.vertices.length; for (vertexIndex = 0; vertexIndex < numVertices; vertexIndex++) { MPoint currentPoint = geom.vertices[(int)vertexIndex]; // Sets OpenGL's render mode to select and stores // selected items in a pick buffer // view.beginSelect(); OpenGL.glBegin(OpenGL.GL_POINTS); OpenGL.glVertex3f((float)currentPoint[0], (float)currentPoint[1], (float)currentPoint[2]); OpenGL.glEnd(); if (view.endSelect() > 0) // Hit count > 0 { selected = true; if (singleSelection) { xformedPoint = currentPoint; xformedPoint.homogenize(); xformedPoint.multiplyEqual(alignmentMatrix); z = xformedPoint.z; if (closestPointVertexIndex < 0 || z > previousZ) { closestPointVertexIndex = (int)vertexIndex; singlePoint = currentPoint; previousZ = z; } } else { // multiple selection, store all elements // fnComponent.addElement((int)vertexIndex); } } } // If single selection, insert the closest point into the array // if (selected && selectInfo.singleSelection) { fnComponent.addElement(closestPointVertexIndex); // need to get world space position for this vertex // selectionPoint = singlePoint; selectionPoint.multiplyEqual(path.inclusiveMatrix); } // Add the selected component to the selection list // if (selected) { MSelectionList selectionItem = new MSelectionList(); selectionItem.add(path, surfaceComponent); MSelectionMask mask = new MSelectionMask(MSelectionMask.SelectionType.kSelectComponentsMask); selectInfo.addSelection( selectionItem, selectionPoint, selectionList, worldSpaceSelectPts, mask, true); } return(selected); }