Showing posts with label c. Show all posts
Showing posts with label c. Show all posts

A new tree addon, Part VII: an all C implementation

As indicated in this BlenderArtists post I have started developing a version of the space tree addon with most of the core calculations performed by C code.

Currently most functionality is available except for apical control and pruning but a 4x speed up (approximately, your mileage may vary) is worth it. This version is at the moment only available for 64bit Windows platforms (because it was difficult enough already to get that running with Visual Studio 2012) and unlike the previous C enhancements there will be no fallback on pure Python.

Code availability

This version is developed in its own branch, 'all_c' and the installation follows the exact same pattern as for other addons (don't forget to remove any older version). The zipfile is located here. As of May 2, 2014, this is linked against the 3.4 Python library as shipped with the Blender dailt build. If you use a slightly older version of Blender you might want to use the previous commit that was linked against 3.3.

The (almost) pure Python version stays available in the master branch, the zip file for this version is located here.

Future developments

I am thinking about making a Linux version available but that's not high on my priorities. If someone is willing to compile the module however I can include it with the addon. I think it is entirely possible to have a csca.pyd and a csca.so side-by-side. Having different .so files for Linux and OSX is something else, that would require tweaking the Python imports based on the OS type.

The current speed improvements only apply to the generation of the tree skeleton. I think the same improvement should be possible for native skinning algorithm. Also, there is yet no optimization of the C code and no multithreading, so we might improve the speed even more.

Another area of interest that I am currently spending time on is creating good leaf textures. Even with a decent flatbed scanner this is not trivial, yet now that spring is in full gear in my hemisphere I have started on cherry, apple and oak leaves.

References

The space tree addon itself is introduced in a few articles on this blog and is available on GitHub. Relevant links are listed below:

A new tree addon, part VI: continuing development

The latest version (0.2.14) includes a module written in C that implements some of the most time consuming functions. The result is a 20 - 30 % speedup for the generation of the branch skeleton. For now this is only available for 64 bit windows but on a different platform the addon will fall back on pure python implementations of these functions so cross platform portability is still guaranteed.

This is a quite noticable speedup: on my machine the generation of a tree consisting of 3000 branch segments went from 3.7s to 2.7s.

Implementation notes

The C extension module was compiled with Visual Studio 2013 and seems to work fine both with the official 2.70 distribution (compiled with MSVC 2008) and with the daily builds (compiled with MSVC 2013) but will only work with 64 versions of Blender. The Visual Studion solution is part of the spacetree repository so if people are interested in porting the module to other platforms they can have a go. Detailed notes on how to compile a native Python extension with Visual Studio 2013 were published in a separate article.

Undocumented stuff

This version of the addon also contains a first try at the implementation of branch shedding.

References

The space tree addon itself is introduced in a few articles on this blog and is available on GitHub. Relevant links are listed below:

Native Python extensions for Blender with Visual Studio 2013

Researching how to create a python module in C with Microsoft Visual Studio 2013 which could be used in Blender caused me quite a few headaches so in order to spare other people the same I wrote this article that illustrates the process in a step-by-step manner. The resulting solution is available on GitHub as well.

Prerequisites

When writing native extensions for Python it is said that it is vitally important to use exactly the same compiler that was used to compiler Blender itself (or rather its embedded Python). This is especially important on Windows where even different versions of Visual Studio may break compatibility. However, I have found that Visual Studio 2013 can be used to compile an extension that is usable both for Blender version compiled with msvc2008 and msvc2013.

Currently the daily builds for Blender are built with Visual Studio 2013. This can be verified by opening Blender and generating the system information from Help -> System Info. In the generated text file (available in the text editor) the line with the Python version should read something like: ...... 1800 64 bit .... The 1800 part is the interesting bit as it identifues the version of Visual Studio, where 1800 means MSVC 2013.

The official Blendet 2.70 release for windows is still built with MSVC 2008 (the version string in the system info will show 1500) but I have found no compatibility issues, but of course your mileage may vary. It is however extremely important to match the platform: a 64 bit extension will only work for 64 bit Blender!

Writing an extension module in C

Starting point when writing an extension is this page. It's a fairly complete but lengthy introduction and its content is platform independent. To actually compile C code into a dynamic library that can be used on Windows additional information is needed. Unfortunately some information on this page is wrong or incomplete (/export:initexample is not needed, the dll needs a .pyd extension) and as there are quite a few confusing steps it might be easier to have all the steps explicitely listed for our Blender scenario.

In the following walkthrough I'll assume that Blender is installed in C:\Blender and that we'll be using MVSC 2013 express edition for Desktop. I also assume you have checked out the Python library that Blender is built with, to C:\BlenderLibraries. We need the source for these libraries for the Python.h include files. (you can checkout these libraries with any subversion client from svn.blender.org, see here for instructions. Make sure you get the 64 bit versions if you are compiling for a 64 bit platform and notice that the folder is called win64_vc12 even though we'll be using msvc 2013)

Ten easy steps

The following steps are needed to create a simple extension. each step is explained in detail below.

  1. Create a new DLL project
  2. Add a new x64 platform if necessary
  3. Configure the extension to use
  4. Configure the include directory
  5. Configure the library directory
  6. Add the library dependencies
  7. Add your source code
  8. Build the project
  9. Copy the library to the Blender installation
  10. Test it from Blender

Create a new DLL project

  • file->new project
  • templates->Visual C++->Win32->Win32 Project
  • name: BlenderTest (can be placed anywhere, leave all default settings)
In the application wizard that opens select DLL and Empty project.

Add a new x64 platform if necessary

i=If you are working on/for a 64-bit platform you'll need to add a x64 platform to your solution.

  • click on the configuration manager [below the menu bar in the task bar]
  • add a new active platform [click on the part that probably displays Win32]
  • select x64 and leave all the default settings

Configure the extension to use

Although a native extension is just a DLL, Python wants it to have a .pyd extension:
In the properties of the BlenderTest project
for all configurations set
Configuration properties -> General the Target extension to .pyd

Configure the include directory

The compiler needs to be able to find the Python.h include file.
for all configurations
Configuration properties -> C/C++ -> General Add 'C:\BlenderLibraries\win64_vc12\python\include\python3.3' to Additional Include directories

Configure the library directory

The Python libraries need to found as well:
for all configurations
Configuration properties -> Linker -> General Add 'C:\BlenderLibraries\win64_vc12\python\lib' to Additional Library directories

Add the library dependencies

Each configuration is dependent on a different library:
for the Debug configuration
Linker -> Input Add 'python33_d.lib' to Additional Dependencies
for the Release configuration
Linker -> Input Add 'python33.lib' to Additional Dependencies

Add your source code

in the Solution explorer, right click the Source Files folder in the BlenderTest project and slect add -> new item. Choose C++ file and give it BlenderTest.cpp as its name (although you're free to choose anything you want)

Copy the example code (you might want to use this) in the editor

build the solution (a warning about an inconsistent dll linkage of round can be ignored)

Build the project

Select the release configuration and click Build -> Build Solution

The module will be in the subfolder BlenderTest\x64\Release and be called BlenderTest.pyd

Copy the library to the Blender installation

Copy BlenderTest.pyd to somewhere where Blender can find it, for example to the site-packages directory within Blenders installation directory (e.g. C:\Blender\2.70\python\lib\site-packages)

Test it from Blender

open the python console in Blender
import BlenderTest
BlenderTest.foo()

The System console (Window -> toggle system console) should show 'Hello World'