Saturday, February 18, 2017

Monday, February 6, 2017

Thursday, December 29, 2016

Thursday, December 1, 2016

Nikon D5 Review

Monday, November 28, 2016

Tuesday, November 22, 2016

My Portable Portrait Lighting Equipment

Thursday, November 10, 2016

Monday, November 7, 2016

Thursday, November 3, 2016

X-Rite Color Checker Passport

Friday, October 28, 2016

Friday, October 21, 2016

NEW!!! DJI Osmo Mobile (Unboxing)

Thursday, October 20, 2016

Friday, October 14, 2016

Sony a6500 vs Fuijfilm X-T2

Sunday, October 9, 2016

Sony a6500 vs a6300

Wednesday, October 5, 2016

Sunday, October 2, 2016

Tutorial - Brenizer Method

Tuesday, September 20, 2016

Sunday, September 18, 2016

Canon EOS M5 vs Fujijfilm X-T2

Friday, September 16, 2016

Thursday, September 15, 2016

My D820 / D850 Expectations

Tuesday, September 13, 2016

Samyang Premium Series Lenses - Preview

Thursday, September 8, 2016

Correct Camera Holding Technique

Monday, September 5, 2016

How To Clean Your Camera?

Thursday, September 1, 2016

How To Clean Lenses?

Wednesday, August 31, 2016

Tuesday, August 30, 2016

85 USD Portrait Monster

Sunday, August 7, 2016

85 f/1.4 vs 135 f/2 vs 70-200 f/2 8

Thursday, August 4, 2016

Nikon 105 f/1.4E Preview

Sunday, July 31, 2016

Fujifilm X-T2 - Ön İnceleme

Saturday, March 8, 2014

The extends decorator

Recently, I was writing a pipeline tool that spanned over a couple of classes. Each of these classes were actually manipulating Maya nodes. So I've a Sequence class manipulating Sequence nodes in the maya scene and a Shot class manipulating Shot nodes but are in communication with my Sequence class and so on.

After a couple of days of coding I've started to feel that what I was doing was not continuous in terms of the experience you got out of them while coding with them. I mean, you first create your own Sequence instances and let them find and store pymel Sequence instances etc.. Maya Sequence nodes are already wrapped with pymel.core.nt.Sequence class and I'm writing a new class that stores the pymel instance and does what it does on top of it. Although, doing so is the general practice in Maya, but I didn't like it this time.

What I would prefer was to directly be able to manipulate the pymel class to have the methods I've written. Then it flashed suddenly to me. The next one is not what I've came up with, it is a step lead me to my final solution.

So, in Python you can easily patch a class in runtime like this:

def create_shot(self, name='', handle=10):
    """Creates a new shot.

    :param str name: A string value for the newly created shot name, if
      skipped or given empty, the next empty shot name will be generated.
    :param int handle: An integer value for the handle attribute. Default
      is 10.
    :returns: The created :class:`~pymel.core.nt.Shot` instance
    shot = pymel.core.createNode('shot', name=name)
    self.set_shot_handles([shot], handle=handle)
    # connect to the sequencer
    shot.message >> self.shots.next_available  # this is another story
    return shot

# and patch the Sequence class
pymel.core.nodetypes.Sequence.create_shot = create_shot

Even though, this seems neat/frightening at first sight, I don't like this kind of patching. The patching is good but the way you patch it is not Pythonic enough to my taste.

What I came up with is the following:

def extends(cls):
    """A decorator for extending classes with other class methods or functions.

    :param cls: The class object that will be extended.
    def wrapper(f):
        if isinstance(f, property):
            name = f.fget.__name__
            name = f.__name__
        setattr(cls, name, f)

        def wrapped_f(*args, **kwargs):
            return f(*args, **kwargs)

        return wrapped_f
    return wrapper

The above decorator, I think, is kind of the most simplest complex code I've ever written. And used neatly as follows:

class SequenceExtension(object):
    """Extension to pymel.core.nt.Sequence class
    def create_shot(self, name='', handle=10):
        """Creates a new shot.

        :param str name: A string value for the newly created shot name, if
          skipped or given empty, the next empty shot name will be generated.
        :param int handle: An integer value for the handle attribute. Default
          is 10.
        :returns: The created :class:`~pymel.core.nt.Shot` instance
        shot = pymel.core.createNode('shot', name=name)
        self.set_shot_handles([shot], handle=handle)
        # connect to the sequencer
        shot.message >> self.shots.next_available
        return shot

So by using it, any Sequence node you get out of Pymel ( will have that method, event the ones you've already created in runtime. And all of the methods are staying in a good place under their own class. So you can now do things like that:

seqs =
shot1 = seqs[0].create_shot('test_shot')

Isn't that beauty.

Wednesday, February 19, 2014

Stalker on GitHub

Stalker is now hosted on GitHub. You can clone the repository or fork the project from the project page.

Wednesday, February 5, 2014

How to Install SetupTools for Maya and use it to install packages

One another quicky about installing SetupTools for Maya (needs root permission):

  1. Download the SetupTools source tarball from PyPi
  2. Extract it somewhere (with "tar -xvzf setuptools-2.1.tar.gz")
  3. Run:
    sudo /usr/autodesk/maya/bin/mayapy /path/to/the/extracted/tarbar/setuptools-2.1/ install
Now you should have easy_install at /usr/autodesk/maya/bin/ try installing something (don't forget being root):
sudo /usr/autodesk/maya/bin/easy_install sqlalchemy

Traceback (most recent call last):
  File "/usr/autodesk/maya/bin/easy_install", line 5, in 
    from pkg_resources import load_entry_point
  File "/usr/lib/python2.7/site-packages/", line 2797, in 
    parse_requirements(__requires__), Environment()
  File "/usr/lib/python2.7/site-packages/", line 576, in resolve
    raise DistributionNotFound(req)
pkg_resources.DistributionNotFound: setuptools==2.1
Interesting isn't it! I don't know what the problem is here, but, here is the workaround:
  1. Run mayapy as root:
    sudo /usr/autodesk/maya/bin/mayapy
  2. Install the package using python:
    from setuptools.command import easy_install
Problem solved!

Rather than trying to use mayapy with root permission, I would love to be able to use virtualenv created against mayapy but for now it seems there are some path issues.

But I have an idea of creating a normal virtualenv for the system python, make it relocatable, and then replace all the paths and symlinks to mayapy. Will try that whenever I have time.

PyCharm, PyMel and Maya and you know, the errors you get out of this setup!

Ok, got something annoying again, and solved it. And to let it be recorded in the great internet of ours, I'm writing down the solution that I've found for it.

The Problem

You hope to be able to setup PyCharm for some fancy unittests including PyMel or Maya. You setup mayapy as it is shown here and you don't want to debug it remotely as shown there, but run your tests right inside PyCharm with mayapy. You've set up your project interpreter as mayapy, and then hit Ctrl+Shift+F10, and gues what you've got this error message:
Traceback (most recent call last):
  File "/home/eoyilmaz/.local/share/pycharm-3.0.2/helpers/pycharm/", line 17, in 
    os = import_system_module("os")
  File "/home/eoyilmaz/.local/share/pycharm-3.0.2/helpers/pycharm/", line 33, in import_system_module
    f, filename, desc = imp.find_module(name)
ImportError: No module named os
What!!! you say, ImportError: No module named os, "os" is one of the built-in module how come you can not find it.

The Solution

When you further inspect the error and the code that generates the error ( you see that PyCharm is trying to use the imp module to find out the package paths, that's very cool but it seems that it is not working with zipped modules. Yes, the zipped modules, like the one that is shipping with Maya. The problem is the file, imp module can not find anything inside this zip file. Then at the moment you've recognized that and get happier, you start to thinking about the last 6 hours you've lost finding this.

To be clear about the solution, unzip the file somewhere that you have write permission and in PyCharm:
  1. Go to "Settings->Project Interpreter->Python Interpreters"
  2. Select maypy
  3. Select "Paths" tab
  4. Remove these (if exists):
    • /usr/autodesk/maya/lib/
    • /usr/autodesk/maya/lib/
  5. I didn't remove these, and it was still working:
    • /usr/autodesk/maya/lib/python2.x/config/
    • /usr/autodesk/maya/lib/python2.x/site-packages
    • /usr/autodesk/maya/lib/python2.x/
  6. Add the path that you've extracted the file, like this:
    • /home/eoyilmaz/Documents/development/MayaPythonLib/python27/
Now run your tests, voila!

I hope it will save some of your hours and hairs!

Monday, January 20, 2014

How to use pymel.core.other.repeatLast

In Maya, and especially with MEL, when you want to add commands to the last used commands menu (you know the one shows up when you hit space) you use the repeatLast command. It is pretty easy, just add the command as a string and add a label to it to show up in the UI etc. as follows:

repeatLast -ac "some MEL command here!" -acl "a descriptive label for the command"
It is easy. Now when you want to do it in Python especially in PyMel, you will punched in the face by seeing that it only accepts MEL commands. I can hear the pipeline engineer inside you saying "I'd use the python Mel command to run Python code inside MEL", not so easy boy, how would you pass all the data. So if what you want to repeat is a function that accepts arbitrary arguments and especially the arguments are Python objects it is impossible to use the repeatLast command as it is. You need some modifications.

So, what I came up with was to store the callable, the arguments and the keyword arguments in somewhere that I know, and then call some python functions that needs only simple arguments (like an integer) from MEL.

Here is the code that I've written for a UI script that repeats the function on UI buttons:
import pymel.core as pm

__last_commands__ = []  # list of dictionaries to store callables and arguments

def repeater(index):
    """repeats the last command with the given index
    global __last_commands__
        call_data = __last_commands__[index]
        return call_data[0](*call_data[1], **call_data[2])
    except IndexError:
        return None

def repeat_last(call_data):
    """own implementation of pm.repeatLast
    global __last_commands__
    index = len(__last_commands__)

    callable_ = call_data[0]
    args = call_data[1]
    kwargs = call_data[2]

    command = \
        'print \\"\\";python(\\\"from oyToolbox import repeater; repeater(%s);\\\");' % index

    repeat_last_command = 'repeatLast -ac "%(command)s" -acl "%(label)s";' % {
        'command': command,
        'label': callable_.__name__


    # also call the callable
    call_data[0](*call_data[1], **call_data[2])

def RepeatedCallback(callable_, *args, **kwargs):
    """Adds the given callable to the last commands list and adds a caller to
    the pm.repeatLast
    return pm.Callback(
        repeat_last, [callable_, args, kwargs]
The only problem here is that the __last_commands__ variable will get fatter and fatter if you call a lot of commands, and Pythons garbage collector will not be able delete anything inside it. A good solution is to delete the list occasionally, limit the element count to the same number of elements in the last commands UI element. Oh one another note, do you see the empty print command in line 28, maya doesn't add anything to the list without it, weird isn't it.

Sunday, January 19, 2014

Preserve query_property() behaviour when using Session instead of ScopedSession

I feel so much hungry about posting something :)

Here is another tip I've come up yesterday night.

What I like about the sqlalchemy.orm.scoping.ScopedSession is its query_property method. Which helps you to setup your classes so it is easier to write queries.

Here is a code showing a normal Sqlalchemy query without the query_propety trick:
from stalker import db, User
db.session.query(User).filter_by(name='Erkan Ozgur Yilmsz').first()
Now with using the query_property, this query can be simplified to:
from stalker import User
User.query.filter_by(name='Erkan Ozgur Yilmsz').first()
As you see I don't need to import the session object and also it is easier to understand and read.

So I was doing that with Stalker.

But last night I've recognized that I'm doing something wrong by using a ScopedSession in our PyQt4/PySide UI scripts, we were getting a lot of errors from our Postgresql database, stating that there are already max connections reached.

Basically, what a ScopedSession does is to have a pool of connections to the database and use them over and over again until the application is closed. It is very good for a Web server (like Stalker Pyramid, more on that later) but it is not correct or at least not correct to use in the same way that I was using it in Stalker.

So I've decided to switch back to the regular Session class which is created by the session_maker() utility. But the down side was that by using a Session object I will loose what query_property was doing for me.

The solution is; to copy/paste and customize the ScopedSession.query_property method for the Session class and Stalker. Here is the customized version that uses the regular Session instance from Stalker:
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import class_mapper
from sqlalchemy.orm.exc import UnmappedClassError

from stalker.models import make_plural

def query_property():
    """A ripped off version of the sqlalchemy.orm.ScopedSession.query_property
    class query(object):
        def __get__(s, instance, owner):
                mapper = class_mapper(owner)
                if mapper:
                    # session's configured query class
                    from stalker import db
                    return db.session.query(mapper)
            except UnmappedClassError:
                return None
    return query()

class ORMClass(object):
    """The base of the Base class

    query = query_property()

    def plural_class_name(self):
        """the plural name of this class
        return make_plural(self.__class__.__name__)

Base = declarative_base(cls=ORMClass)

PickleError in Sphinx 1.2

Now lets start giving some tips and tricks:

Trying to build documentation with Sphinx 1.2 for Stalker I got the following message:
PicklingError: Can't pickle : attribute lookup sqlalchemy.ext.declarative.api.Base failed
Last year I was also having this same error message and I've solved it by downgrading to Sphinx 1.1.3. But this time I wanted to solve it.

Because I'm not deeply informed about the internals of Sqlalchemy, it didn't catch my attention at the first glance but if you look at the module sqlalchemy.ext.declarative.api you will find nothing about the Base that Sphinx is complaining about.

So I've figured out that my Base class that I'm generating with sqlalchemy.ext.declarative.declarative_base() ends up being referenced from that module.

So the following lines were creating the problem:
from sqlalchemy.ext.declarative import declarative_base

class ORMClass(object):
    """The base of the Base class

Base = declarative_base(cls=ORMClass)    
The solution was to add the following lines to the Sphinx
import sqlalchemy.ext.declarative.api
from stalker.db.declarative import Base
sqlalchemy.ext.declarative.api.Base = Base
Now at the build time of the docs there will be a Base in the api module, and it will not mess my library cause it is in Sphinx'

News on Stalker

Another year has passed and I've posted only once.

I had lots of things, technical tips and tricks to post. Also I've wanted to inform you guys about Stalker and what we (me and my wife) were doing about it. But always pulled myself back with one thing in my mind "it is not a finished product, there are tons of missing features here and there, so I can not announce it yet!".

And it is still not a finished product and I still don't want to announce it. But you should know that we are using it in production of a feature animated movie here in Anima Istanbul, and it is going very well. At the end of the movie we will certainly have a full fledged Open Source ProdAM and an Open Source Pipeline Library that will make things easier for a lot of studios that wants to develop their own pipeline.

So, please be patient and wait.

Saturday, January 5, 2013

Fix Maya 2012 and PyQt Crash under Fedora 17

After a very long break, here is my first post.

It is about fixing Maya 2012 (or any other maya version suffers) and PyQt (actually pretty much all the python libraries depending on libssl) crash under Fedora 17 Beefy Miracle.

The problem is about the and which is linked in /usr/autodesk/maya/lib/ and /usr/autodesk/maya/lib/ Qt doesn't like them, and actually any library depending on openssl doesn't like them. What you need is the good old 0.9.8 version of the openssl library. And you can download it from a couple of sources, here is one

The mentioned package is for CentOS but it seems that it is ok for Fedora 17. Just download the package and install it by running the following command:

sudo rpm -i openssl098e-0.9.8e-17.el6.centos.2.x86_64.rpm

and then replace the symlinks:

sudo ln -sf /usr/lib64/ /usr/autodesk/maya/lib/
sudo ln -sf /usr/lib64/ /usr/autodesk/maya/lib/

Thats all, you are good to go.

Sunday, June 10, 2012

Anouncing oyProjectManager 0.2.4

I had a couple of weeks which I can reserve to oyProjectManager, and a couple of requests which could improve the overall user experience. So it is here, check the changelog and the documentation and I've updated the installation instructions. And you can download the source code here.

Among the changes these are the highlights:
  • Assets and Shots now supports statuses
  • Assets can have a user defined type, like "Prop", "Character", "Vehicle" etc.
  • New user interface to manage asset and shot statuses called "status_manager"
  • project_manager can now edit shot info like start_frame, end_frame, handles and thumbnail
If you were already using oyProjectManager, you need to update your database, for now I'm leaving you alone on that process.

A possible way can be dumping the whole database to an sql file and then let oyProjectManager create a new empty database  and then import the sql file and according to the complains of your database engine edit the sql and re-import it. But on later versions I should supply database upgrade scripts.

Hope you like this version. And don't hesitate to drop me an email if you have ideas which will improve the system.

Edit 1:

Here are some screenshots


Edit 2:
Uploaded oyProjectManager to PyPI with little fixes to documentation and UI titles.

Wednesday, April 25, 2012

Anouncing oyProjectManager v0.2.3

Nearly two and a half years ago I've started a project called oyProjectManager. It was a simple pipeline tool written in Python and it was using PyQt4 for UI. This tool helped us a lot to sort things out in this past two years. Before, it was a chaos to manage files and asset versions.

When I first started this project I was not very experienced with OOP, design patterns and abstraction concepts like MTV or MVC or methodologies like TDD etc. So I've ended up with a useful tool, which is designed and programmed not in the best way.

Seven months ago, I was trying to write an automated backup script, which simply finds all the nuke files in the project folder structure and copies all the inputs (by using rsync) to the filtered backup folder in the server.

Then I've realised that I can not go with the system any more because it was very hard to get some data which will be very simple if the system was designed correctly. I was trying to avoid adding big design changes to the system for a long time because I was already writing a new complete Production Asset Management System (ProdAM) for the last 2 years called Stalker, which is another open source project and deserves a couple of posts in this blog, and any code I will add to oyProjectManager will be meaningless cause I've already correctly designed Stalker and I am going to use it in the near future. But it seems that I still had time before starting to use Stalker, so I've started to write oyProjectManager from scratch this time by following TDD practices. I've fixed a lot of things, misconceptions, bad code led by bad design. But again I couldn't go too far (didn't add any Project Management capabilities).

Previous versions of oyProjectManager were using project specific XML files to store simple data and it was storing the metadata information in file names, thus it was limited in terms of how much and what kind of data will be stored in the system. The file naming convention was static (constant, fixed) and limited, and the resultant project structure was firmly tied to this naming convention and because of that the project structure was bad, the assets were spread around the whole project structure, models were there, rigs here, shots there etc (following Maya's own project structure). It was dirty. Also there was a misconception about what an asset is: I was calling every single version file an Asset which is obviously is false.

After v0.2.0 of oyProjectManager all the project structure, the placement of individual version files and the name of these files are all defined by Jinja2 templates. So you can easily create a complex project structure. And because the metadata is hold in a proper database (it can be any type of database that SQLAlchemy supports, the system is heavily tested for SQLite3 and loosely tested for PostgreSQL) it is much more easier to query the data and the system works lighting fast when compared to the previous implementation. For the last 4 months we were using oyProjectManager in our studio and everybody was very happy about it.

Anyway, the new version is up an running. And if you want to use it in your own facility visit oyProjectManager's PyPI page to download the source code and here is the documentation.

The documentation doesn't have a section which is explaining the installation yet. But it is simply as follows:

Automated install:
  1. Download and install Python 2.6 (that is because most of the programs are still using 2.6)
  2. Download and install setup tools
  3. Run:
    easy_install-2.6 oyProjectManager
    This will install oyProjectManager to your pythons dist-packages folder with all its dependencies
  4. Copy all the packages to a shared folder, which is visible to other computers in your studio
  5. Add this shared folder path to PYTHONPATH environment variable to let all the applications to see the modules.

As a side note I need to state that even though I've run the installation code above in Linux we are using mostly Windows and OSX based workstations, there was no problem running SQLAlchemy nor Jinja2 in those systems. May be they were not able to use the C extensions those are supplied with SQLAlchemy and Jinja2 but the general speed is more than ok already.

Manual install:
  1. Download oyProjectManager and extract it and copy the oyProjectManager folder to a shared folder which all of your workstations are able to see
  2. Download SQLAlchemy and again extract it to a shared folder
  3. Do the same for Jinja2
  4. Add this shared folder path to PYTHONPATH environment variable to let all the applications to see the modules.
  1. If you don't plan to use another interface library and do all that nasty coding by your self I also strongly suggest you to install PyQt4 or PySide for all to your applications (Maya, Nuke, Houdini etc.) and use the UI coming with oyProjectManager. Because installing PyQt4 and PySide is a little bit involving, I'm leaving you by your self about how to install it. For a quick tip search for MyQt4 for Maya, and you can use my post about compiling PyQt4.
  2. Newer versions of Nuke comes with PySide installed, to be able to use PySide instead of PyQt4, add a new environment variable to Nuke's startup script ( called "PREFERRED_QT_MODULE" and assign the value "PySide"

  1. oyProjectManager needs two environment variables to be defined, REPO and OYPROJECTMANAGER_PATH

    REPO: set to a path where you want to save your projects. This is typically a mapped drive like "M:\Projects" for Windows and or a mount like "/mnt/M/Projects" in Linux and OSX.

    OYPROJECTMANAGER_PATH: The path that contains the "" file, which is the configuration file for the system (I also suggest to use this folder to place your SQLite3 database file)

    See the documentation of the config file

    for the details about
  2. You should be ready to go, run maya, be sure that maya is able to see the directory you have copied the modules in to and run:
    from oyProjectManager.environments import mayaEnv
    from oyProjectManager.ui import version_creator
    mEnv = mayaEnv.Maya()
    When you run the above script, you should be able to see the version_creator UI. Which as the name suggests creates new versions for some assets or shots.
    The interface should explain itself. But because you didn't created any Project yet you will not be able to create any assets or shots or versions.
  3. To bring up the project_manager interface use the following code:
    from oyProjectManager.ui import project_manager
    This will show up a new interface where you can create and edit Projects, Sequences and Shots.

    You can also run the project_manager from the regular Python shell if you have successfully installed oyProjectManager, SQLAlchemy and Jinja2 to your Python.

I hope you will like oyProjectManager and how it helps you to work more easily and organize your files, and drop me a line if you are having problems installing it or you have suggestions for the next releases.

I will do another post showing the scripting part of oyProjectManager and how to create data easily by using plain Python.

And again the real bomb is Stalker, wait for it.

Friday, December 2, 2011

Autoload in SQLAlchemy

A quick tip,

If you want your data models to autoload their contents as you create them, you can use the following idiom:

I generally use three python modules in my database related (thus using SQLAlchemy) applications, one for the declarative Base (, one for the database url, session, query and engine ( and a last one for the models (

In the

from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

In the

from declarative import Base
engine = None
session = None
query = None
metadata = Base.metadata
database_url = None

def setup(url="sqlite:///:memory:"):
    global engine
    global session
    global query
    global metadata
    global database_url
    # to let my models to register them selfs 
    # and fill the Base.metadata
    import models
    database_url = url
    engine = sqlalchemy.create_engine(database_url, echo=False)
    # create the tables
    # create the Session class
    Session = sqlalchemy.orm.sessionmaker(bind=engine)
    # create and save session object to session
    session = Session()
    query = session.query
    return session

Setting up the database becomes db.setup(), easy enough.

In the

import db
from declarative import Base

class MyClass(Base):
    __tablename__ = "MyClasses"
    id = Column(Integer, primary_key=True)
    name = Column(String(256), unique=True, nullable=False)
    description = Column(String)
    def __new__(cls, name):
        if name:
            # get the instance from the db
            if db.session is None:
                # create the session first
            obj_db = db.query(MyClass).\
            if obj_db is not None:
                # return the database instance
                # skip the __init__
                obj_db.__skip_init__ = None
                return obj_db
        # if we are here,
        # it means that there is no instance
        # in the database with the given name
        # so just create one normally
        # And SQLAlchemy queries will use this part
        return super(MyClass, cls).__new__(cls, name)
    def __init__(self, name):
        # do not initialize if it is created from the DB
        if hasattr(self, "__skip_init__"):
        = name

In the above example the __init__ method is unnecessarily included to show how to skip the __init__ when there is an instance retrieved from the database.

The key in the above example is the usage of __new__ and using the super to hand the class creation to Type as shown above, this will trigger __init__. We can not just return because the class will not be initialized and we should skip the __init__ for instances returned from the database.

So by using this idiom, you should be able to restore an instance without querying it:

from model import MyClass
import db


myC1 = MyClass(name="Test")
myC1.description = "To show the instance retrieved correctly"

myC2 = MyClass(name="Test")
print myC2.description
# this should print:
#     To show the instance retrieved correctly

Thats all, easy and smooth...

Edit: Now I need to note that SQLAlchemy also uses __new__ to create new instances, but we prevent it doing another query again inside __new__ by checking the name argument, which is not used by SQLAlchemy when restoring from database.

Sunday, November 6, 2011

My first iDevice

Last week, I recieved an iPad as a gift from my boss (I should not talk about what kind of nasty things that I had to do to get this gift ;) ), anyway now I've officially entered to the world of Apple.

First impression, I've liked it a lot. I was always talking about how much a tablet is useless for me because I have a smartphone and a laptop, but it seems that after getting it you start to find a lot of use for it.

Now I'm reading all my emails and news feeds (and writing this post) on iPad and I'm planning to sign up for magazines like 3D World (as I see there is no digital version of Cinefex for now).

I'm lucky because they didn't make fun about me that much at work, cause, as an Android fun and phone owner (SGS 2) even though I was always talking about how much I hate about Apple's money oriented policies, I always stated that as a tablet iPad is better than any android tablet (except the Advent Vega) and recommended iPad to anyone asking what to buy.

The only thing that I'm missing is the lack of Android grade sharing. In Android, the sharing functionality is something more universal than it is in iOS. For example, when you install an app that allows you to share something, it is automatically listed in the sharing targets. Like StumbleUpon, it is listed in any application that wants to share something. But in iOS, as I see, it is not working like that, the app needs to be programmed in that way to be able to use StumbleUpon as a sharing target. For now it is a big minus for iOS.

On the other hand, Eventhough it doesn't have dual core A5 CPU and the powerfull PowerVR SGX 543 GPU of iPad 2, I've liked the smoothness of the interface.

I definetely liked the battery life. I was able to use it for two days continously without recharging it. I am still amazed how long the battery stays in %100 even while watching video on the internet.

I very much liked the consistent style of iOS apps which is another nice feature that Android apps are missing.

I liked iPad...

Tuesday, November 1, 2011

Planning to switch to a Macbook Pro and OSX

I'm still using my HP HDX 18 notebook, it is 3 years old now. And last year I bought a Macbook Pro 13 for my wife, ever since that time I felt pure envy. So I decided to buy a Macbook Pro 17 to myself when the Pre-2012 versions become available.

Because I hate using two operating systems at the same time (aka dual boot) I need to decide which operating system I should use, Ubuntu or OSX. So I thought listing what I like and hate will help to choose one.

What I like about MBP and OSX:
  • The build quality of Macbooks are incredible.
  • Multi-touch trackpad is awesome. After using my wifes macbook pro a couple of minutes and switch back to mine, I still tend to keep scrolling with two fingers (very intuitive), which is obviously not working.
  • OSX has better support to MBP hardware (arguable)
  • You can get more juice out of your battery (even with powertop and custom hacks under linux you get around 6 hours where as you get 7-10 hours in OSX)
  • Wake up and sleep are incredible, still can not believe how fast it sleeps and wakes up (inevitable)
  • Native gamma adjustment tool is incredible, still can not get correct gamma response under linux with the only tool for me is nvidia control panel (need more r&d on this subject)
  • All Adobe programs (Photoshop and Lightroom mostly) are working natively (but I need to state that I hate Adobe), using alternatives like Gimp sometimes doesn't satisfy your needs as CMYK files can not be read in Gimp and trying to give a chance to Wine will leave you with no pressure sensitivity under PS CS 5, CS3 works fine though and for Bibble, eventough their creative photo retouching tools are absolutely better than Lightroom (I think it is because Lightroom doesn't want to step into Photoshop's shoes) I'm still not liking the vibrance tool in bibble (it is more or less like saturation where it should not change the skin colors) and the performance in linux compared to windows is very slow.
  • Diablo III will work natively under OSX where as under linux the only chance to get this adorable piece of art to work is Wine, although wine is very nice and most of the time smooth, running a windows program with wine is not comparable to running it nativeley under OSX (I wouldn't think that I was going to say that I'm liking an os because of a game but it is true I'm very excited about Diablo III)
  • OSX is based on FreeBSD, so you will feel at home with the terminal and shell commands
  • It has the same tools with linux like rsync so my backup script will still going to work (o-oh I forgot that OSX doesn't support ext4 and my external backup drive is using EXT4, so I need to convert it to EXT2 or HFS or something else)
  • space/preview is working adorably (Gnome-Sushi is not working that flawless)
  • drag&drop was not so fun before
  • The way that the applications are installed and placed on a consistent place (/Applicatons)
  • Pycharm and WingIDE are working in the same way as they are in linux.
What I don't like about MBP and OSX:
  • No numeric pad, so it seems that I need to get use to it (no deal breaker)
  • Houdini under OSX doesn't support Qt and PyQt4, at least I couldn't manage to run it, even though I compiled the Qt, Sip and PyQt4 against houdini's python 2.6 (this was the deal breaker for me, when I was trying to finish a project on a Mac Pro and OSX, where in the middle of the night I installed Ubuntu and 30 minutes later of my switch I was working happily under linux with everything working smoothly)
  • Another for Qt, compiling it for Maya 2012 OSX and then writing a bash script to link all the dylibs to Nuke's Qt libs took like 3-4 days to figure out, where as under linux it is enough to copy the PyQt4 folder and the Sip related files to nukes site-packages folder, and as I mentioned before Qt is not working for Houdini OSX (may be I'm missing something).
  • No apt_get, this is a horrible deal breaker, I heard about macports, but they say that time to time it will leave you with broken packages where you can't downgrade nor upgrade.
  • The OSX community is not very technical compared to linux (though there are very successful open source package developers who are using OSX), it becomes very important if you try to build a pipeline over the three operating systems and can not find a solution for something very simple.
  • Application based alt+tab switching still confuses me how do you switch between windows of the same program, expose? (but I've liked the gnome-shell implementation, where you can use the arrow key after alt+tab while holding alt key) As Chris has pointed using command+~ (tilde) switches between the windows of the same application and I found that using command+tab and arrow keys shows the preview of the windows of the chosen application, so I think I'm going to be fine when I start using osx, apparently it the lack of information that hardens my experience in osx. 
  • May be I'm missing something but why the green plus button on the tittle bar is not maximizing the window to the screen sometimes. Seems that it is fixed or working as predicted in OSX Lion.
On the other hand, there are couple of things annoying me in linux:
  • like the high cpu usage bug which is still not solved for the last 3 years I was in the linux world
  • I slowly started to feel tired about always fixing something
  • It started to feel like it is not complete as a package
  • Applications are spread out all over the system, you can find things installed under /usr, /usr/local, /usr/local/share, /usr/share, /opt/, /var, /var/local, /var/opt etc.
  • still can not solve the Samba speed issue, and NFS is using UTF-8 in Linux and ANSI in Windows, so having a windows server with NFS, any Turkish characters in the filenames (which means that I need to kill somebody by the way) will leave you with a file name with "?" characters in the best condition.
  • others mentioned above
But I need to state that I'm in love with Ubuntu and if I finally decide to switch to OSX completely, it is going to be like tearing my heart off, if I will not turn back in 2 weeks.

But change is good time to time. So it seems like I'm going to give another chance to OSX besides, it was Houdini who made me left OSX before ;)

posted from Bloggeroid

Monday, September 19, 2011

Switched to PyCharm

I was using WingIDE for the last 2 years and I loved it. It was and it still is a great Python IDE. Recently in the mailing list of WingIDE they were talking about how great PyCharm is and what is missing in WingIDE and where PyCharm fails.

Anyway I downloaded the trial version of PyCharm and started to use it. At the beginning I hate it. Basically it felt slow and there were couple of other things that I was very much used to use in WingIDE and they were missing in PyCharm (it was my mistake, they were all present but I need to search for them).

I didn't touch it for 2 weeks and then after what, I don't remember, I've opened it up again and started to read the quick tips. And I found that all the things that made me to switch back to WingIDE was there. And there were a lot more things which are enhanced and working properly in PyCharm and it supports more languages, has tons of options to customize the way it works etc. Somehow I felt that even the program feels slower, I'm coding faster. There are tons of shortcuts for TDD development, you need to watch this video.

There is a "Back to school office sale" where you can buy the personal version of PyCharm for $49 instead of $99. Which is very much reasonable when you think that I paid $230 for WingIDE ( $195 Wing IDE 3 + $35 to upgrade to WingIDE 4, but the latest price for WingIDE Pro 4 - Non Commercial is $95 which is in the same margin with PyCharm Personal without the discount.).

So I bought PyCharm and I'm very happy using it.

Wednesday, April 13, 2011

Houdini BUG: ERROR: Couldn't open "Fuse11.0.658/FUSE_ColorOptions.ui" for reading

This is a bug report I've created for Houdini 11.0.658 and it also gives a workaround for the problem. I'm publishing it here cause there is no solution on the web (or at least I couldn't found any).

Under Mac OSX 10.6.6 setting HOUDINI_PATH environment variable to a path either in ~/.profile or in .MacOSX/environment.plist causes Houdini to crash on startup. The terminal outputs the following error messages:

Stereo1s-Mac-Pro:MacOS stereo1$ echo $HOUDINI_PATH
Stereo1s-Mac-Pro:MacOS stereo1$ pwd
/Applications/Houdini 11.0.658/
Stereo1s-Mac-Pro:MacOS stereo1$ ./houdini
ERROR: Couldn't open resource file "resources" (No such file or directory)
Can't open dophints.cmd
ERROR: Couldn't open "Fuse11.0.658/FUSE_ColorOptions.ui" for reading: No such file or directory
Color name 'ListEntry1' is missing from the theme.
Color name 'ListEntry2' is missing from the theme.
Couldn't find font Proportional.12 - using default instead
Couldn't find font Proportional.9 - using default instead
Couldn't find font Proportional.9 - using default instead
Couldn't find font Proportional.9 - using default instead
Couldn't find font Proportional.9 - using default instead
Couldn't find font Proportional.9 - using default instead
Couldn't find font Proportional.9 - using default instead
Couldn't find font Proportional.9 - using default instead
(and this last line repeats around 100 times)

and adding "/Library/Frameworks/Houdini.framework/Versions/11.0.658/Resources/houdini" to HOUDINI_PATH at least lets houdini to open properly but the interface is not looking the same before (I think it is not loading my personal preferences this time).

To fix the preferences issue then I have also added "$HOME/Library/Preferences/houdini/11.0:/Users/Shared/houdini/11.0:$HIP/houdini" to the HOUDINI_PATH and everything works as expected right now.

So the final HOUDINI_PATH looks like this:


But under Windows setting the HOUDINI_PATH didn't cause any problem like that.

Monday, January 17, 2011

Taking The Pleasure of Suspend/Hibernate on Ubuntu

Suspend and Hibernate had always been a problem with my laptop in Ubuntu. I believe I've finally fixed it.

I first tried to use the s2disk and s2ram tools which are installed with uswsusp (sudo apt-get install uswsusp). It fixed my hibernation but not suspend. I then, tried a couple of tweaks suggested in this page. But it didn't fixed my suspend problem again (though the settings are still present, I think they are helping me anyway).

Then I downloaded the latest bios+flash utility from HP. But, there was a problem, the utility is written for Windows.

I tried to search for information about how to flash bios under linux, there is a nice forum page here, but I didn't try to use these methods cause I was not sure if my laptops flash utility was going to work under FreeDOS (but in the installation program it say it is working under FreeDOS-XP-2000-Vista-7, thanks to HP not sharing this information).

Then I found a Windows XP Live CD edition (not sure if it is legal) which nicely worked, and voila I've flashed the latest bios and all my suspend problems went away.

I'm now taking the pleasure of being able to suspend and resume my laptop without a problem.

Saturday, November 27, 2010

Back to Ubuntu :)

All right, I'm back to Ubuntu again. I'm so much surprised how much I've missed that little one. After playing with Kubuntu for the last 1.5 year, coming back to Ubuntu feels much better right now. I know that it is very much a personal taste to have one of them but Gnome feels much better, solid and faster after playing with KDE for a long time. Lately Kubuntu started to feel laggish. And previously I was kinda forced to move to KDE because of the sticky key problem I was having under Maya 2009. And with the new Qt interface of Maya 2011 I don't really have anything chaining me to KDE any more.

So, I consider myself greeted by my Ubuntu fellas.

And a note about my move, if you want to do the same thing and want to move from Kubuntu to Ubuntu, just insall ubuntu-desktop by using:

sudo apt-get install ubuntu-desktop

then if you don't like to have the kde programs you can remove them or there a couple of ways to have kde and gdm together and don't have ones program listed in other ones menu.

Friday, November 12, 2010

Sleeping Princess - Prensesin Uykusu

My first movie will be out there in the theatres next weekend. I participated to the movie as being the Visual Effects Supervisor and also the Lead Technical Director.

I would love to dive in to the technical challenges we've been through, but I will just give some screen shots from the movie this time.

Just go and watch the movie, it's a good one from the great director Cagan Irmak.