| McNeel Wiki | |||||
| edit · print · help · all topics | |||||
Main Pages
Languages
| Note for .NET developersThe .NET equivalent to this article can be found at SdkExtendRhinoScript OverviewWith the Rhino 4.0 SDK, it is now possible to write plug-ins that extend the RhinoScript scripting tool. In order to do this, a plug-in must do the following:
ExampleIn the following example, we will create a new plug-in named TestScript that support RhinoScript scripting. If you are familar with creating C++ projects that support COM automation and you just want to review the sample plug-in source code, then you can download it here. Also, the purpose of this example is not to teach COM Automation or to explain how the .IDL file work or what Variants are. There is plenty of information in MSDN and on the Internet that explain these areas. Step 1: Create a plug-in that support Automation Launch Visual C++ 2005 and create a new Rhino Plug-in project named TestScript. On the Plug-in Settings page of the Rhino Plug-in Appwizard dialog box, make sure to check the Automation check box. One the Appwizard has completed creating the skeleton project, build the project.
Step 2: Create a COM object that supports IDispatch Create a new MFC class by running the MFC Class Wizard. Name the class CTestScriptObject. This class should be derived from CCmdTarget. Also, under Automation, select the Automation radio button. Note, this COM object will not be creatable by type ID because Rhino plug-ins (DLLs) are dependent on Rhino.
Step 3: Add methods to your object An object is not useful unless you expose methods or properties. In this example, we will create a new method that allows the scripter to add point objects to Rhino. Within Class View, select your new object's interface and add a new method using the Add Method Wizard. Give the new method the name of AddPoint. It should have a single VARIANT* argument and return a VARIANT.
Step 3: Implement your methods The Add Method Wizard will create a placeholder for our AddPoint method in TestScriptObject.cpp. Add the following code to your new method:
VARIANT CTestScriptObject::AddPoint(VARIANT* vaPoint)
{
VARIANT vaResult;
VariantInit(&vaResult);
V_VT(&vaResult) = VT_NULL;
if( vaPoint )
{
ON_3dPoint pt;
if( VariantToPoint(*vaPoint, pt) )
{
CRhinoDoc* doc = RhinoApp().ActiveDoc();
if( doc )
{
CRhinoPointObject* obj = doc->AddPointObject( pt );
if( obj )
{
doc->Redraw();
ON_wString wstr;
ON_UuidToString( obj->Attributes().m_uuid, wstr );
CString str(wstr);
V_VT(&vaResult) = VT_BSTR;
vaResult.bstrVal = str.AllocSysString();
}
}
}
}
return vaResult;
}
In the above code, the VARIANT* argument is converted to an ON_3dPoint using the VariantToPoint() function. One of the biggest challenges to creating RhinoScript accessable objects is converting the COM Variant data type to an openNURBS data type and back. Fortunately, I have done all of the work for you. The sample project mention above includes a number of utility function to help you convert Variant data type to a number of openNURBS data types. There are also a number of function to do just the opposite. Just look for the VariantUtilities.h/cpp files. Once the Variant has been converted to an ON_3dPoint, the code simply adds the point to Rhino. But, just like RhinoScript's AddPoint method, this method also returns the object's unique identifer. Step 4: Allow access to your object Now that you have a COM object that implements IDispatch and has at least one method, we can allow access to it. The easiest way is to put a copy of your new COM object on your plug-in object as a data member. For example:
class CTestScriptPlugIn : public CRhinoUtilityPlugIn
{
public:
CTestScriptPlugIn();
~CTestScriptPlugIn();
// Required overrides
const wchar_t* PlugInName() const;
const wchar_t* PlugInVersion() const;
GUID PlugInID() const;
BOOL OnLoadPlugIn();
void OnUnloadPlugIn();
// Optional overrides
LPUNKNOWN GetPlugInObjectInterface( const ON_UUID& iid );
private:
ON_wString m_plugin_version;
CTestScriptObject m_object;
};
Then, allow access to the object by overriding the GetPlugInObjectInterface() virtual function. For example:
LPUNKNOWN CTestScriptPlugIn::GetPlugInObjectInterface( const ON_UUID& iid )
{
LPUNKNOWN lpUnknown = 0;
if( iid == IID_IUnknown )
lpUnknown = m_object.GetInterface( &IID_IUnknown );
else if( iid == IID_IDispatch )
lpUnknown = m_object.GetInterface( &IID_IDispatch );
if( lpUnknown )
m_object.ExternalAddRef();
return lpUnknown;
}
Note, RhinoScript will only request an IDispatch object from your plug-in. Also because our object is a data member of our plug-in object, we must increment our object's reference counter. Otherwise, when ""VBScript" releases our object, which will decrement the reference counter, our object will be destroyed. This will cause your plug-in to crash. Step 5: Implement your methods Once you have implemented your methods, you can begin to test them. Launch Rhino and use the PlugInManager command to install your new plug-in. Then, use RhinoScript's EditScript dialog to test the methods in your plug-in's object. The following code demonstrates how to get our plug-ins scriptable object and run the AddPoint method.
| ||||
| rename · changes · history · subscriptions · lost and found · references · file upload | |||||