// ================================================================== // Copyright 2012 Autodesk, Inc. All rights reserved. // // This computer source code and related instructions and comments are // the unpublished confidential and proprietary information of Autodesk, // Inc. and are protected under applicable copyright and trade secret // law. They may not be disclosed to, copied or used by any third party // without the prior written consent of Autodesk, Inc. // ================================================================== using System; using Autodesk.Maya.OpenMaya; [assembly: MPxNodeClass(typeof(MayaNetPlugin.apiMeshCreator), "apiMeshCreatorCSharp", 0x0008105b)] namespace MayaNetPlugin { class apiMeshCreator : MPxNode, IMPxNode { /* Attribute initialization. */ public static MObject size = null; public static MObject shapeType = null; public static MObject inputMesh = null; public static MObject outputSurface = null; [MPxNodeInitializer()] public static void initialize() // // Description // // Attribute (static) initialization. // { MFnNumericAttribute numAttr = new MFnNumericAttribute(); MFnEnumAttribute enumAttr = new MFnEnumAttribute(); MFnTypedAttribute typedAttr = new MFnTypedAttribute(); // ----------------------- INPUTS ------------------------- size = numAttr.create("size", "sz", MFnNumericData.Type.kDouble, 1.0); numAttr.isArray = false; numAttr.usesArrayDataBuilder = false; numAttr.isHidden = false; numAttr.isKeyable = true; addAttribute(size); shapeType = enumAttr.create("shapeType", "st", 0); enumAttr.addField("cube", 0); enumAttr.addField("sphere", 1); enumAttr.isHidden = false; enumAttr.isKeyable = true; addAttribute(shapeType); inputMesh = typedAttr.create("inputMesh", "im", MFnData.Type.kMesh); typedAttr.isHidden = true; addAttribute(inputMesh); // ----------------------- OUTPUTS ------------------------- outputSurface = typedAttr.create("outputSurface", "os", new MTypeId(apiMeshData.id)); typedAttr.isWritable = false; addAttribute(outputSurface); // ---------- Specify what inputs affect the outputs ---------- // attributeAffects(inputMesh, outputSurface); attributeAffects(size, outputSurface); attributeAffects(shapeType, outputSurface); } public override bool compute(MPlug plug, MDataBlock datablock) // // Description // // When input attributes are dirty this method will be called to // recompute the output attributes. // { if (plug.attribute.equalEqual(outputSurface)) { // Create some user-defined geometry data and access the // geometry so that we can set it // MFnPluginData fnDataCreator = new MFnPluginData(); fnDataCreator.create(new MTypeId(apiMeshData.id)); apiMeshData meshData = (apiMeshData)fnDataCreator.data(); apiMeshGeom meshGeom = meshData.fGeometry; // If there is an input mesh then copy it's values // and construct some apiMeshGeom for it. // bool hasHistory = computeInputMesh(plug, datablock, meshGeom.vertices, meshGeom.face_counts, meshGeom.face_connects, meshGeom.normals, meshGeom.uvcoords); // There is no input mesh so check the shapeType attribute // and create either a cube or a sphere. // if ( !hasHistory ) { MDataHandle sizeHandle = datablock.inputValue(size); double shape_size = sizeHandle.asDouble; MDataHandle typeHandle = datablock.inputValue(shapeType); short shape_type = typeHandle.asShort; switch( shape_type ) { case 0 : // build a cube buildCube(shape_size, meshGeom.vertices, meshGeom.face_counts, meshGeom.face_connects, meshGeom.normals, meshGeom.uvcoords ); break; case 1 : // build a sphere buildSphere(shape_size, 32, meshGeom.vertices, meshGeom.face_counts, meshGeom.face_connects, meshGeom.normals, meshGeom.uvcoords ); break; } // end switch } meshGeom.faceCount = meshGeom.face_counts.length; // Assign the new data to the outputSurface handle // MDataHandle outHandle = datablock.outputValue(outputSurface); outHandle.set(meshData); datablock.setClean(plug); return true; } return false; } // // Description // // This function takes an input surface of type kMeshData and converts // the geometry into this nodes attributes. // Returns false if nothing is connected. // public bool computeInputMesh(MPlug plug, MDataBlock datablock, MPointArray vertices, MIntArray counts, MIntArray connects, MVectorArray normals, apiMeshGeomUV uvs) { // Get the input subdiv // MDataHandle inputData = datablock.inputValue( inputMesh ); MObject surf = inputData.asMesh; // Check if anything is connected // MObject thisObj = thisMObject(); MPlug surfPlug = new MPlug( thisObj, inputMesh ); if ( !surfPlug.isConnected ) { datablock.setClean( plug ); return false; } // Extract the mesh data // MFnMesh surfFn = new MFnMesh(surf); surfFn.getPoints( vertices, MSpace.Space.kObject ); // Check to see if we have UVs to copy. // bool hasUVs = surfFn.numUVsProperty > 0; surfFn.getUVs( uvs.ucoord, uvs.vcoord ); for ( int i=0; i