Brief of pillow in English
Pillow is a light weight application on which I' m working lately, the current aim is to make a simple modeller along the lines of commercial modeller silo. The project is at a very early stage implementing some basic modelling operations, such as "move", "rotate", "scale", "weld", "split" on objects and sub-objects like vertices, edges and faces, and also catmull-clark subdivision. Because pillow is under developing, there are problems, but it is still a good start point for me, 'cause as far as I know, lots of teams of identical applications take a long time to develop, normally in years, and pillow is only a 2-month job that I' m doing alone.
On history:
I got the idea of doing a modeller of myself in Oct 2004, at that time I was learning directx by myself, and I thought of actually making something to get familiar with the skills, so I decided to write this application. I set the silo modeller as my goal, for one thing, silo adapts a reasonable set of shortcut keys which I believe can speed up the progress of modelling, and also, silo is small in size. However, after I had the idea, I didn't have the time to concrete it until this summer, I got myself graduated. I have bunch of names for this application, first "cedar" and then "polygon studio" and "clayshop", and now I' m calling it "pillow".
On code:
Since I decided to practice directx with pillow, the first version is written with c# and managed directx. I also used a game engine called truevision3d, because functions like object-picking are out there already. But due to the huge data structures of game engine, the code's performance was very poor. So, then, I tried to code directly with directx. The current version is rewritten with c++ and opengl. The GUI library I use is wxwidget. I always care a lot about the user interface of my program. I don't think the appearance of products is of trifle. If the gorgeous design of apple computer was taken away, the company that never compatible with others would not survive in the market. However, I cannot find a good GUI library for my job, I need a cross platform, open source, skinable library with plenty of controls. While doing this application, I tried cegui, wxwidget, qt4, and picked up wxwidget finally.
The code is divided into 3 main layers, the ui layer undertakes the job of interacting with users, and displays the result of operations. The scene layer is in the middle, managing the 3d scene, converting the graphics operations to primitive operations on data structures. This part is actually the core of the whole program. The data structure is in the deepest layer which contains the data of the scene. The communication between the scene layer and the data layer is strictly defined as a set of commands; every command is tracked by a thing called history manager to enable users to restore at any time. As in the image, blue arrow is the flows of commands, the purple one is commands recording and the red ones are the data flows.
Currently, pillow doesn't support undo and redo. Although I already implement these operations, I didn't combine them with the ui. Because this part is easy to leak memory, I need to make sure other parts works fine before I add these functions.
when I was coding undo and redo part, I first thought of making commands, and every command has its inversion, and when I need to undo an operation, I simply call the inverse command. Yet, some operations, say calculating the average number, don't have commands in inversion. I could keep a record of the situation before the average happens, but this is a silly way. and then I thought up dividing the operations into layers, because no matter how complex a graphics command might be, it finally modifies the primitive data structures and the primitive operations on data structures can be simply defined as "new", "modify", "remove", so I only need to keep a record of these basic operations to hold the history of all the graphics operations. Actually, there are dozens of primitive operations defined in my code, more than just "new", "remove" and "modify".
So what is history manager? It is an undo queue and a redo stack, commands are pushed into the head of the queue, if they reach the end of the queue, and they are discarded. When the user wants to undo a step, a command will be popped and executed, at the same time, an inverse command be pushed into the redo stack. And if redo happens, just do everything in the backward.
How to prevent memory leak? My design is centralizing the management of all pointers; this is what I call data pool. It is actually a dynamic array to store pointers. Every function can use the data, but cannot new it or release it. There are two ways to release the data, first, if the remove operation needs to be recorded by the history manager, pass the pointer to the history manager, and as the record log is discarded by the history manager, the pointer is released. Second, if the operation does not need to be recorded, release it directly through the data pool. By adopting this, I can guarantee that, at any time, every data in the heap has at least one pointer stored in the data pool.
One more thing:
When I first showed people my idea of doing pillow, somebody asked what the unique feature of my polygon modeller is, since there are so many of them. I do want to do something special, but just before going creative, I need a base. And this is why I make pillow. I dreamed of making an application that combines the traditional sculpture progress with the cg making operations enabling people to create the shape more directly. I have already found some directions like the commercial software zbrush, mudbox and the teddy demo. So this is what I really wanna do in the future. Hope I can insist on doing this.
Some resources:
A tutorial on box modelling in pillow:
http://billconan.blogspot.com/2006/10/pillow-01a.html
A piece of flash showing how pillow works in action:
http://billconan.blogspot.com/2006/10/wink.html
2 comments:
那几张图好抽象,为什么不用Visio之类的工具画一下呢?
想艺术一下,用手写板在photoshop里画的。
Post a Comment