Migrating a SketchUp C++ API Plugin to SketchUp 2013

 

The SDK shipping with SketchUp 2013 has two parts: a new API, and a new import/export plugin interface.  Like the original SketchUp C++ SDKs (SkpReader and SkpWriter), the SketchUp 2013 SDK allows third party developers to write plugin importers and exporters for SketchUp as well as standalone applications that read and write SketchUp files.

 

The new API differs both in technology and in structure.  It uses a pure C interface (no more COM!), providing access to a SketchUp model and the entities it contains. The model can be loaded from a file or created from scratch in memory. Currently the API does not allow interaction with an active model in a running SketchUp process.

 

The new import/export plugin interface allows you to create a plugin DLL that will either export data from the active SketchUp model, or import data into the active SketchUp model.

 

If you have a standalone application that is using SkpReader/SkpWriter to read from and write to .skp files, you may continue to use these old APIs for the time being. You can find SkpReader and SkpWriter under the ‘deprecated’ directory inside the new SDK package. However, please note that the SkpWriter API is now deprecated, and support will be dropped fully with the release of SketchUp 2014. Support for SkpReader will be dropped fully with the release of SketchUp 2015. Therefore, you are advised to port your code to the new API at your earliest convenience.

 

If you have an importer and/or exporter DLL, you can get them running within SketchUp 2013 by only updating your code to use the new plugin interface. This should be relatively straightforward and you’ll find step-by-step instructions below to guide you. We have updated the SkpReader example from the old SDK package to use the new plugin interface as a working example. You can find the migrated ‘skptoxml’ example inside the ‘deprecated’ directory of the SDK package.

 

Migrating a SkpReader-based Exporter plugin to SketchUp 2013

Exporter plugins are now required to:

 

1.    Provide an implementation of SketchUpModelExporterInterface. However, for existing SkpReader-based exporters, we provide a secondary interface called SketchUpDeprecatedModelExporterInterface which can be implemented instead. This deprecated interface allows continued use of the SkpReader API.

2.    Return a pointer to the concrete object that implements this interface.

Here are the general steps to convert an existing exporter:

 

·         Exporters are no longer required to be COM servers, so you may delete all COM-boilerplate functions such as DllRegisterServer, DllUnregisterServer, DllGetClassObject, DllCanUnloadNow. You may also delete the AtlModule implementation class, if you have one.

·         Write a class that derives from SketchUpDeprecatedModelExporterInterface. This new class will essentially be the replacement for an existing class that you should already have, i.e. the class that implements ISketchUpExporter, ISupportExporterOptions, ISupportExporterAbout, etc. You will find that most existing member functions have counterparts in the new interface. For example:

DoExport => DeprecatedConvertFromSkp

get_Id => GetIdentifier

get_Count => GetFileExtensionCount

get_FileExtension => GetFileExtension

get_Description => GetDescription

GetOptions => ShowOptionsDialog

ShowSummary => ShowSummaryDialog

 

·         Delete the include statement for SketchUpAddin.h since that file declared the old plugin interfaces.

·         On Windows, export a function called GetSketchUpModelExporterInterface that returns a pointer to your concrete object that is implementing SketchUpDeprecatedModelExporterInterface. This object should stay alive during the entire export operation. So, you may want to use the Singleton design pattern to manage the lifetime of this object. Here’s an example from the ‘skptoxml’ sample project:

 

SketchUpModelExporterInterface* GetSketchUpModelExporterInterface() {
 return CXmlExporterPluginWin::GetInstance();
}

·         On Mac, provide an implementation of the SketchUpModelExporterPlugin protocol. Similar to the exported function on Windows, this protocol provides a function to obtain a pointer to the
concrete object that is implementing SketchUpDeprecatedModelExporterInterface. See modelexporterplugin.h for the definition of this protocol.

·         Implement the conversion in your override of DeprecatedConvertFromSkp. Note that the first parameter of this function is a pointer to the ISkpDocument interface of the SketchUp model you are exporting. You can cast this pointer to ISkpDocument* and continue to use your existing SkpReader-based conversion code.

·         The old progress feedback interface, IProgressCB, has been replaced with SketchUpPluginProgressCallback. The new interface is almost identical to the old one with the exception of the SetProgressMessage function, which now takes a UTF-8 encoded std::string instead of a COM BSTR.

·         Make sure Runtime Type Information (RTTI) is turned on in your C++ compiler settings.

 

You should now be able to build the project and use your exporter within SketchUp 2013.


Note: On Mac, the underlying implementation of BSTR has changed. It can no longer be directly cast to/from NSString. Possible implementations of conversions to/from an NSString are given below. For an example, see deprecated/SkpReader/Examples/SkpStats.


_bstr_t NSStringToBSTR(NSString* str) {
  return _bstr_t([str UTF8String]);
}

NSString* BSTRToNSString(_bstr_t str) {
  const char* buf = static_cast<const char*>(str);
  return [NSString stringWithUTF8String:buf];
}

 

Migrating a SkpWriter-based Importer plugin to SketchUp 2013

Importer plugins are now required to:

 

1.    Provide an implementation of SketchUpModelImporterInterface.

2.    Return a pointer to the concrete object that implements this interface.

 

Legacy plugins written using SkpWriter can be migrated using a shim plugin. A Windows example of this can be found in the SDK under deprecated/SkpWriter/Examples, with the two projects SkpWriterImporter and SkpWriterImporterShim.

SkpWriterImporter is a plugin importer for SketchUp 8 built with Visual Studio 2005. It does not actually import any data from a file, given it’s just sample code demonstrating how to interact with the model. It simply adds a bit of geometry to the active SketchUp model.

SkpWriterImporterShim is a sample plugin importer for SketchUp 2013, built with Visual Studio 2010. Its purpose is to adapt the SketchUp 2013 importer plugin harness to a SketchUp 8 importer plugin. It basically maps the equivalent functions between the SketchUp 2013 and SketchUp 8 harnesses. As with the exporter APIs, you will find that most existing member functions have counterparts in the new interface. For Example:

 

ConvertToSkp => ConvertToSkp

GetImporterInfo => GetDescription, GetIdentifier, GetFileExtension

ShowSummary => ShowSummaryDialog

DoOptions => ShowOptionsDialog

These two projects demonstrate how a SketchUp 8 importer plugin DLL--without having to be rebuilt--can be added to SketchUp 2013.

Creating a shim DLL

Creating the shim DLL is fairly straightforward. The basic process is:

1.    Write a class that derives from SketchUpModelImporterInterface, using the normal process to build a SketchUp 2013 importer plugin DLL, except that all the implemented functions should be stubbed out.

2.    In the shim class’s constructor, manually load the legacy plugin and any dependency DLLs it has in reverse order. This assures that the DLLs will be loaded properly by the legacy DLL.

3.    Get the SketchUpImporterInfo data from the legacy plugin by calling its GetImporterInfo() function.

4.    Implement the property access functions in the interface by returning the SketchUpImporterInfo data. For example: GetDescription(), GetIdentifier(), GetFileExtension(), etc. This will require conversion from UTF-16 strings to UTF-8.

5.    Implement the SU2013 ConvertToSkp() function by calling the legacy plugin’s ConvertToSkp() function.

6.    If desired, implement the ShowOptionsDialog method by calling the legacy plugin’s DoOptions() function.

 

Once the shim plugin is built, it can be used within SketchUp 2013.  It just needs to be copied along with the original plugin to the SketchUp 2013 Importers folder. Note that it’s also necessary to copy any DLLs needed by the plugin as well, including SkpWriter.dll, xerces-c_2_6, and any Visual Studio 2005 libraries that may not already be installed.