2010年8月31日星期二

Weekly update 2010/8/23-29

跟UI打交道的一周.

Qt Model/View architecture:
Model: QModelIndex, internalPainter is used to associate the custom item pointer to the QModelIndex, the custom item class is defined by us and is used to store the custom data.
View: there are mouse press/release/doubleclick/move event, the row and tree branches(grew lines) can be redraw by overriding drawRow/drawBranches function.

Others:

1. 之前假如不是跟geometry/mesh相关的工作,我都有一点点抵触, 觉得不对口。现在发觉不能这样子,想做跟geometry/mesh相关的工作内容是因为想在那方面做深入, 但是有时候做做别的东西也能扩展知识面, 而且东西都不是独立而是相联系的。例如现在在看Qt的model/view architecture, 从pattern从编程方面都是会有益的。例如做paint layer blend mode, paint layer transfer, layer mask就能扩展texture/material这方向的认识。

2. 写代码,接触一个feature甚至是fix 一个bug时候,一定要进行做的完善完美鲁棒, 否则之后的bugs会不断过来,弄得无法开始or专心于下一步的工作。

3. 要到LayerModel/LayerView(custom 的Model/View)中加入新的model item, 而且这些item还是新的类型, 于是觉得:冷静->逻辑清晰->快速的理解能力很重要.

4. 想起了去年面试被问过的一个question: 给出三角形的三个边长, 怎么求出三角形的面积?
假如在初高中时候要是这个问题都不懂的话肯定考不上大学,如今却真的模糊了。后来复习时候发现那个公式原来有个不错的名字Heron’s (or Hero’s) formula. A=sqrt(s*(s-a)*(s-b)*(s-c)), where s = (a+b+c)*0.5, http://en.wikipedia.org/wiki/Heron's_formula, 链接中还给出了利用余弦定理law of cosines的证明(这个更重要). 这些其实都是应该牢记的。最后提到了这个公式的数学稳定性不好numerically unstable, http://en.wikipedia.org/wiki/Numerical_stability, 里面对一个array 求sum的例子不错, 求一百个数, 假如一个是1,另外99个都是0.01,精确解释1.99,但是看上去正确的算法得到的结果不同,有些甚至是错误的(错误的是先加1再加0.01, 较好的做法是先排序, 从小到大来加. 排序?复习)。这可能是2进制计算机中由于round-off error and truncation error而引入的 (ok, 又涉及到了floating point numer了, 怎么表示,跟0的比较,之前看过一个用它生成random number的)。
然后又从truncation提到了Taylor series (这个我在研二暑假找实习时候被问及), 除了能写出这个公式之外,还得想想它有什么实际用处. (1). F(x) = F(a) + F’(a)x +…当 a=0时候就变为Maclaurin series, 然后就可以求例如the exponential function e^x的近似值了, sin(x)的近似值等。

5. 有这么一个Camera model, 有意思的是我想在初始化时候都是给出position, target等参数parameters, 但是这个camera model中确实根据给出的scene center and scene radius来计算那些参数.
6. Tree data structure.
for example, max-heap is a complete binary tree, which used to build the priority-queue;
the RB-tree is binary search tree, which is used to build the set and map container.
there are many other examples of course. scene tree...

2010年8月20日星期五

Weekly update - 2010/8/16

Basic shader manager and vertex batch
There are many things to learn and do. In order to render the curvature tensor, which is property of mesh, i need to add shader step-up and organize the vertices from curvatures into vbo (OpenGL 3.x is used).
However, there is already shader step-up and vbo using in the scene::render(), i don’t want to duplicate the code in the class Model. So, shader manager and vertex batch classes are need.
After googling, i come across to http://www.informit.com/articles/article.aspx?p=1616796&seqNum=4, the free chapters of OpenGL SuperBible 5th, and the greatest thing is its code is stored in google code project, from where i can download it. Must read!
Another resource is http://prideout.net/blog/?p=22 (anti-aliased cel shading, and shader wrapper).

Expected result:
1. Refactor the shader loading, create the batch class, render the scene(world frame, grid, mesh) using this new one.
2. render the curvature tonsor.
3. integrate the anti-aliased cel shading.

Notes:
1. there are two ways to get the vertex attribute location(index). The explicit way, use the
glBindAttribLocation(uint program, int index, char *name);
The inexplicit way, use the
int index = glGetAttribLocation( uint program, const char *name );
the index will be used later by puting vertex data into it.
2. To render the model, there is only mesh data at the current time, which is a polygon/n-sided mesh, using GL_TRIANGLES, a triangle mesh is created. The triangle mesh is used exclusively on rendering, but the mesh adjacency information is not used so data is wasted to record that. After integrate the GLBatch from GLTools of OpenGL SuperBible 5th, I wonder how about remove the triangle mesh, put the triangle data of the polygon mesh into the a instance of class GLBatch.
After further investigation, it is found that there is no index buffer object in the class GLBatch, for example if a quad is needed to be drew, six vertices are needed, and the
glDrawArray(GL_TRIANGLES, 0, 6);
is used. There are two vertices are duplicated. The GLBatch cannot be used directly.
But the triangle mesh is still needed to be removed. I want to create a vertex batch for all the vertices data, and create two index buffer object, one for regularly drawing triangle(GL_TRIANGLES) and one for drawing polygon wireframe(GL_LINES).

2010/8/17

Curvature tonsor

The principal curvature directions (red line for KMax, green line for KMin) are renderred using the the flat shader of the stock shaders in GLTools/GLShadermanager.h/cpp.

To build up the 3*3 tensor matrix (used by the Normal Cycle approximation algorithm), need to loop and search a neighborhood region of a start vertex.
push the start vertex into a stack (why use stack);
while stack is not empty
v = pop up the top vertex;
loop the one-ring neighbor of v;
if the neighbor meets the qualify, operate on it and push it into stack.

This search algorithm remind me of the Dijkstra’s algo.

To improve the curvature quality, some smoothing steps are need.

Triangle is evil?
Doing with mesh, i always asking why the quad mesh is used so often and i saw most of the model created by so-called artist are quad mesh, not triangle mesh, not even the n-sided mesh.
Maybe, this is one of the reason.
(a). Two quad faces share one edge, it is easy to set these two faces are symmetric.
(b). Tessellate those two faces in (a) into triangles, what happen the red triangles are set to symmetric? It’s wrong i guess, the topology are not symmetric, though the vertices are symmetric.
(c). even worse.

Thinking about managing ImageFilter/MeshBrush
In the plugin “Image Filter Tool”, there are some image filters can be applied to the image. There is a base class ImageFilter, i can write derive class of it in another plugin(dll) to define new image filter. My question is after the new image filter type is defined, how to add it into the main application, and create ui(for example button, or combo item) for it?
The function registerImageFilters(...) can be put into a ImageFilterFactory class as a static member functon:
typedef (ImageFilter *)(FuntionPointer)();
void ImageFilterFactor::registerImageFilter(string name, FuntionPointer funcPointer);

Can it be better?
(1). do not create the instance until the filter is selected.
(2). do not use the callback function to create the instance in plugin, but use running time type info(rtti) to create a instance in the main application. Declare a new image filter like this:
class ImageFilter : public XObject {
X_OBJECT
...
};
in plugin:
class XImageFilter: public ImageFilter {
X_OBJECT
...
};
Something looks like the object system in Qt :-) then the XImageFilter type is added into the object system, later we can check whether we have a type named “XImageFilter” in the object system, if yes, we use:
ClassInfo * findClassInfo(“XImageFilter”);
ImageFilter *pIF = pCI->createInstance();

Recommended book: Design of Design http://www.informit.com/store/product.aspx?isbn=0201362988 sample chapters are on the right hand side.
(some one said “Run, you run” can be translated into 跑啊, 你丫快跑啊:-)

Bug Series - angle between two vectors

float dot = dot(v0, v1);
float radian = acos(dot);

more safe:
dot = Max(-1, Min(dot(v0, v1), 1); // make sure the dot is [-1, 1].
radian = acos(dot);

https://docs.google.com/document/pub?id=1KyKbHUXfrXh-7L0g4cP-l2QcqVDsmYPTyBJXjGAtXhA

Bug Series_Programing_link error_unresolved external symbol

之前
最上层的基础库都是static library(.lib), 中间的core要是static library(.lib), 然后被应用层的main.cpp直接生成application.exe.

这么弄一直没有问题, 直到...
直到我想加入一个ImageEditor的plugin, 作为一个dynamic library(.dll)存在, 这个plugin需要使用core提供的interface来调用application里面的类和member function, 而core在里面也需要能检查到这个加入的plugin并使用它。

compilation没有问题,但是在link时候就出错了:

error LNK2019: unresolved external symbol "__declspec(dllimport) public ...

后来发现那个core作为static library是有问题,因为static library不能包含别的static library和dynamic library . 于是我把core作为dynamic library就ok了.

但是这样又引入了新的问题, dynamic library需要导出一些接口,别的.dll/.exe才能使用, 否则例如main.cpp和ImageEditor中就不能使用了。
于是就引入了__declspec attributes.

http://blog.csdn.net/alicehyxx/archive/2010/01/08/5161868.aspx
http://msdn.microsoft.com/zh-cn/library/9h658af8(v=VS.80).aspx
http://msdn.microsoft.com/zh-cn/library/z4zxe9k8(v=VS.80).aspx
http://msdn.microsoft.com/zh-cn/library/fdy23fx6(v=VS.80).aspx
http://msdn.microsoft.com/zh-cn/library/a90k134d(v=VS.80).aspx
http://msdn.microsoft.com/zh-cn/library/900axts6(v=VS.80).aspx

Math Series - Cycloid 摆线 轮滚线

想象这么一个情景:车子来开,一个车轮压到地面的口香糖,口香糖粘到轮子上了(会这样子么?) 假如问轮子转一圈之后口香糖划过的距离长?:-)

首先这个划过的曲线叫做轮滚线,一个很形象的名字,至于那个长度怎么求了嘛,以及这个曲线跟地面的面积怎么求,请看:
http://tutorial.math.lamar.edu/Classes/CalcII/ParaArea.aspx and the next section.

2010年8月3日星期二

interesting stuff about geometry

1. a mesh composes of vertex attributes(geometry information) and adjacency(topology information). How about compress they independently? http://openctm.sourceforge.net/

2. Some special mesh can be generated automatically, does not need to add faces/vertices manually. check http://prideout.net/blog/?p=44 and http://structuresynth.sourceforge.net/

3. I'm always interested in the geometry engine of CAD or something like that. http://wildcat-cad.blogspot.com/