Saturday, December 28, 2013

QtCreator and linking minGW .a libraries

Started with my coding side project again and messed with the linking of .a shared library files. These "archive" files are the same thing as Visual C++ .lib files, but QtCreator does not like them and so they must be manually linked. Lib files can be added through dialog.

First step that I failed to do (really basic mistake :)) is to export the functions in dll in the first place. Otherwise one can link to libraries forever and still get unresolved errors. To export functions or classes in Qt Creator library project, simply add Q_DECL_EXPORT to function or class declaration in header. For example: int Q_DECL_EXPORT mult(int a, int b);

Next thing is to figure out, how to add .a libraries to .pro file so that they link. I found it out with a round trip as I tried to generate .lib based on existing .dll. This is actually really simple and involves a few steps (tips from page http://adrianhenke.wordpress.com/2008/12/05/create-lib-file-from-dll/):
  • open Visual C++ command prompt: Start -> Microsoft Visual Studio 2010 -> Visual Studio Command Promt;
  • type command: dumpbin /exports C:\yourpath\yourlib.dll
  • this dumpbin command actually gave me a sign that my functions are not exported as they were not listed in output
  • copy the names from this section:
ordinal hint RVA      name

1    0 00017770 jcopy_block_row
2    1 00017710 jcopy_sample_rows
3    2 000176C0 jdiv_round_up
4    3 000156D0 jinit_1pass_quantizer
5    4 00016D90 jinit_2pass_quantizer
6    5 00005750 jinit_c_coef_controller
...etc
  • paste names into a text file with .def extension and add EXPORTS as the first line:
EXPORTS
jcopy_block_row
jcopy_sample_rows
jdiv_round_up
jinit_1pass_quantizer
jinit_2pass_quantizer
jinit_c_coef_controller
  • run command: lib /def:C:\mypath\mylib.def /OUT:C:\mypath\mylib.lib
  • copy lib file to include directory and add it using Qt library adding dialog: right click in .pro file and "Add Library...
The added command block can also understand .a files so you don't actually need to create .lib files. It looks like this:

win32:CONFIG(release, debug|release): LIBS += -L$$PWD/include/ \
    -lsimplemaths
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/include/ \
    -lsimplemaths
else:unix: LIBS += -L$$PWD/include/ -lgraphclasses -lsimplemaths
INCLUDEPATH += $$PWD/include
DEPENDPATH += $$PWD/include

The -l addition in the beginning replaces the "lib" part in library file name, so "libsimplemaths" becomes "-lsimplemaths".

Basically this is it but it took me some hours to find out why my simple dll does not link. Tried VC++ dll's and lib's also but there are other problems with compiler differences and they don't work with minGW.


Tuesday, November 26, 2013

Running Synology DSM on virtual machine

This post will be about running modified Synology Diskstation Manager on a virtual machine and thus emulating a NAS that can be accessed through web and managed like an ordinary Synology device. The modified version of DSM is called XPenology and it can be found at xpenology.org It can take some fiddling to get it to work (took me a few hours) so I better make a post about it before I forget :)

Primary steps involved are:
1. Creating a new virtual machine using Oracle VirtualBox
2. Booting the VM with disk image that comes with XPenology download
3. Accessing virtual diskstation and installing modified DSM on it
4. Everything works... or not

Creating a new virtual machine

First step in creating a virtual NAS is to create a new virtual machine that can run Synology software. Diskstations run on 64-bit Linux OS, so virtual machine must also be set up as a Linux machine. I used Debian 64-bit, but others could also work.

There are two main things to set up for VM and host computer: boot disk image and network adapter settings. VM boot device must be an existing IDE device that points to disk image downloaded from XPenology forums. Network adapter must be first set up un host computer by creating a bridge between Oracle VirtualBox Network and Local Area Connection. Select both of them in the list of networks, right click and select Add Bridge (or something similar). In VM settings, navigate to network settings and select Birdged Adapter as network adapter. Name should be the name of the bridge and under advanced settings, set MAC address to either 00113208D63C or 00223208D63C. First one is suggested in different forums, but it didn't work for me (more on that later).

When network settings and boot image are all set, start the VM. It should boot up and end up showing "Diskstation login:"

Installing modified DSM on VM

Start up Synology Assistant and search the network for Diskstations. If all goes well the VM will show up as DS3612xs device. Right click on it and select "Install". Point to the downloaded modified version of DSM, fill necessary fields and start the install.

To be continued...

Monday, November 4, 2013

Nuke 7 plugin development

Today I started setting up the dev environment for Nuke 7 plugin development. As I bumped on some small obstacles, I thought I'd better make a post about it.

Nuke 7 plugins should be compiled with Visual C++ 2010 and if you have 64-but OS then against 64-bit libraries. The thing that gave me a little headache was the 64-bit environment. Nuke installation contains an example project that you can load and that should ideally build without problems. But problems I got...

First problem was in VC++ with setting additional dependencies. Nuke plugins need header files and .lib static libraries from Nuke program folder that must be manually added. For some reason VC++ did not want to show me the project properties dialog. After some messing around I found out this was because I didn't have x64 environment set up and so VC++ did not understand the project settings.

To set up the x64 stuff Windows x64 SDK must be installed. There came the second problem. Both the web installer and ISO image installer gave strange cryptic errors. After some more messing around I discovered that it was due to a conflict with already installed 2010 redistributables. I uninstalled all 2010 packages and after that the SDK installed without problems.

Now VC++ allowed to change project settings and add additional dependencies. In addition to Nuke libraries and headers, Windows SDK lib folder must also be pointed to in linker settings. It must be the x64 sub-folder because otherwise you get the linker unknown external symbol errors.

With all things set up I was able to successfully compile the example project:


Monday, October 14, 2013

New books: one here three to go

Checked my company account and found that I can afford some more interesting and useful books. Using Krisostomus web store I ordered the following units of paper and ink:

The Art and Science of Digital Compositing 2nd edition
Ron Brinkmann


This book can probably be called the Bible of compositing. Ron Brinkmann is the mastermind behind Shake software and is consulting The Foundry in Nuke development.


Matchmoving: The Invisible Art of Camera Tracking 2nd edition
Tim Dobbert


THE book about matchmoving. All the nitty-gritty details behind the magic.


Illusion of Life: Disney Animation
Frank Thomas & Ollie Johnson


A very nice book about Disney studio history and animation in general.


Digital Video and HD: Algorithms and Interfaces 2nd edition
Charles Poynton


Book about everything in digital video from aquisition to colour science to video compression schemas to whatnot. This book already arrived, others are waiting in line.

Tuesday, August 13, 2013

Programming continued... vol 4

Have to start working now, so maybe last update in some time.

Latest improvements:
  • plugin system :)
  • ops with geometry operations
  • 3D view
  • viewer Op options for style overrides, also enables sorting of viewed table
Plugin system is a must in any program worth it's weight, so with some fiddling and hatchetwork I pulled this off. Program now checks the /plugins directory at startup and loads .dll libraries that comply with Op interface. From app side this works nice and easy, plugin development on the other hand is, in lack of better word, interesting. To make use of my nice knobs or in fact any other functionality in main app, all source files must be also added to plugin project. This gets them to compile but each plugin is as big as the application itself! Each file references functions in other files and makes this whole thing a bloody tangled mess. I believe it could be possible to make plugins that don't need to clone the whole program to work. At least other people can make this work...Clearly my lack of programming skills is showing its face here :)

In addition to ops with tables, new ops that create or modify geometry are now in place. Started coding a simple library of geometric primitives also, so that generic functions could be used on all of them for inserting vertices etc.

3D view is working as a proof of concept at the moment. Nothing special there and no 3D ops yet. Works on OpenGL.

Viewer Op is now officially an Op and so came functionalities. One can do style overrides, enable sorting of data tables and force points and lines to show constant size and width.

Ahaa, almost forgot! ComboBoxes and other knobs can update their content, for example Combo that lets user select a column for some operation now updates its values from input.


Thursday, August 8, 2013

Programming continued... vol 3

Long time ago I crossed my limits of understanding in programming, but still, through luck and nice findings I still keep fiddling with my little project. During last week I have come from Qt's "Elastic nodes" example to something that almost looks like a functional prototype.

Biggest improvements are:
  • major UI overhaul from node-editor to multiple dockable areas that contain DAG view, table view and node properties
  • knob callbacks work! With some pure luck I managed to get the callback thing working
  • knobs can be added to Op with only one line of code in Op::knobs method
  • new Ops: simple sort (column and direction) and SQL queries
  • nodes can be attached to existing edges by dragging
  • keyboard shortcut to connect viewer to selected node
  • properties view shows knobs for added nodes. Node parameters subwindow can be closed and opened again by double-clicking the node and last opened is positioned on top. 
UI is now based on dockable widgets so that layout can be changed. Look is customised with stylesheet file.

Knob callbacks work nicely, the idea how it should work came one morning and I quickly scribbled some code on a piece of paper. It worked without zero modifications! Adding knobs is very similar to how it works with Nuke plugin development. Syntax is like: "String_knob(callback, &value, label);" where callback is a knob_callback pointer, value is Op variable that is associated with knob, and label is knob label. Knobs get added into row layout that takes care of label and knob placement. In addition I created functions (Nuke style again) to modify last added knob. For example ADD_VALUES(callback, "Ascending, Descending"); adds value list to last knob (ComboBox or similar). Knobs show tooltips and whole node subwindow shows help info when you click on ? button :)

SQL queries took some fiddling with my datamodel because at the moment it is built on QStandardItemModel. To make queries I have to push items into sql database (QSQLITE internally), make the query, and then put items back to model. All Select commands work great but for some reason I can't get queries that modify table structure or delete row to work. They execute when they are hardwired into code but through UI these queries just don't work.

Node area got some love also, because I was annoyed by dragging every connection manually. So now nodes can be inserted into existing edges. One thing is yet to do with node editor - ability to resize backdrops. At the moment they show the resizing dot in the corner but resizing is not working.

Monday, August 5, 2013

Programming continued... vol 2

Getting into exciting stuff now :) Added TableOp base class for operations on data tables and also created three basic operations that subclass TableOp: read table (from comma-separated textfile), select rows, append rows. Ops have pure virtual function called "engine" which calls all node inputs (and through node->execute() calls  their ops) and queries for input data. Data is asked by these calls up to input nodes (read or create nodes) and from there it pours down again. When all node's inputs are executed, node can also execute its ops. So node graph evaluation and execution are not really tied together. Graph evaluation serves the purpose of detecting circular dependencies and displaying order of operations.

Next step is to add table view into main window, because this floating piece is not very nice, and to add possibilities to edit node parameters through UI. I think it needs some kind of callback mechanism but I am not sure yet how to approach this and whether the signal-slot stuff works for it. Main problem is that each node must define its own knobs and there must be connection between every instance of node, it's knob values, and instance's variables.