//- // ========================================================================== // Copyright (C) 1995 - 2005 Alias Systems Corp. and/or its licensors. All // rights reserved. // // The coded instructions, statements, computer programs, and/or related // material (collectively the "Data") in these files are provided by Alias // Systems Corp. ("Alias") and/or its licensors for the exclusive use of the // Customer (as defined in the Alias Software License Agreement that // accompanies this Alias software). Such Customer has the right to use, // modify, and incorporate the Data into other products and to distribute such // products for use by end-users. // // THE DATA IS PROVIDED "AS IS". ALIAS HEREBY DISCLAIMS ALL WARRANTIES // RELATING TO THE DATA, INCLUDING, WITHOUT LIMITATION, ANY AND ALL EXPRESS OR // IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. IN NO EVENT SHALL ALIAS BE LIABLE FOR ANY DAMAGES // WHATSOEVER, WHETHER DIRECT, INDIRECT, SPECIAL, OR PUNITIVE, WHETHER IN AN // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, OR IN EQUITY, // ARISING OUT OF ACCESS TO, USE OF, OR RELIANCE UPON THE DATA. // ========================================================================== //+ // // File: offset.cc // // Description: // Example implementation of a deformer. This node // offsets vertices according to the CV's weights. // The weights are set using the set editor or the // percent command. // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class offset : public MPxDeformerNode { public: offset(); virtual ~offset(); static void* creator(); static MStatus initialize(); // deformation function // virtual MStatus deform(MDataBlock& block, MItGeometry& iter, const MMatrix& mat, unsigned int multiIndex); // when the accessory is deleted, this node will clean itself up // virtual MObject& accessoryAttribute() const; // create accessory nodes when the node is created // virtual MStatus accessoryNodeSetup(MDagModifier& cmd); public: // local node attributes static MObject offsetMatrix; // offset center and axis static MTypeId id; private: }; MTypeId offset::id( 0x8000c ); // local attributes // MObject offset::offsetMatrix; offset::offset() {} offset::~offset() {} void* offset::creator() { return new offset(); } MStatus offset::initialize() { // local attribute initialization MFnMatrixAttribute mAttr; offsetMatrix=mAttr.create( "locateMatrix", "lm"); mAttr.setStorable(false); mAttr.setConnectable(true); // deformation attributes addAttribute( offsetMatrix); attributeAffects( offset::offsetMatrix, offset::outputGeom ); return MStatus::kSuccess; } MStatus offset::deform( MDataBlock& block, MItGeometry& iter, const MMatrix& /*m*/, unsigned int multiIndex) // // Method: deform // // Description: Deform the point with a squash algorithm // // Arguments: // block : the datablock of the node // iter : an iterator for the geometry to be deformed // m : matrix to transform the point into world space // multiIndex : the index of the geometry that we are deforming // // { MStatus returnStatus; // Envelope data from the base class. // The envelope is simply a scale factor. // MDataHandle envData = block.inputValue(envelope, &returnStatus); if (MS::kSuccess != returnStatus) return returnStatus; float env = envData.asFloat(); // Get the matrix which is used to define the direction and scale // of the offset. // MDataHandle matData = block.inputValue(offsetMatrix, &returnStatus ); if (MS::kSuccess != returnStatus) return returnStatus; MMatrix omat = matData.asMatrix(); MMatrix omatinv = omat.inverse(); // iterate through each point in the geometry // for ( ; !iter.isDone(); iter.next()) { MPoint pt = iter.position(); pt *= omatinv; float weight = weightValue(block,multiIndex,iter.index()); // offset algorithm // pt.y = pt.y + env*weight; // // end of offset algorithm pt *= omat; iter.setPosition(pt); } return returnStatus; } /* override */ MObject& offset::accessoryAttribute() const // // Description: // This method returns a the attribute to which an accessory // shape is connected. If the accessory shape is deleted, the deformer // node will automatically be deleted. // // This method is optional. // { return offset::offsetMatrix; } /* override */ MStatus offset::accessoryNodeSetup(MDagModifier& cmd) // // Description: // This method is called when the deformer is created by the // "deformer" command. You can add to the cmds in the MDagModifier // cmd in order to hook up any additional nodes that your node needs // to operate. // // In this example, we create a locator and attach its matrix attribute // to the matrix input on the offset node. The locator is used to // set the direction and scale of the random field. // // Description: // This method is optional. // { MStatus result; // hook up the accessory node // MObject objLoc = cmd.createNode(MString("locator"), MObject::kNullObj, &result); if (MS::kSuccess == result) { MFnDependencyNode fnLoc(objLoc); MString attrName; attrName.set("matrix"); MObject attrMat = fnLoc.attribute(attrName); result = cmd.connect(objLoc,attrMat,this->thisMObject(),offset::offsetMatrix); } return result; } // standard initialization procedures // MStatus initializePlugin( MObject obj ) { MStatus result; MFnPlugin plugin( obj, "Alias", "3.0", "Any"); result = plugin.registerNode( "offset", offset::id, offset::creator, offset::initialize, MPxNode::kDeformerNode ); return result; } MStatus uninitializePlugin( MObject obj) { MStatus result; MFnPlugin plugin( obj ); result = plugin.deregisterNode( offset::id ); return result; }