2008年12月14日星期日

定制右键标记菜单

在dagMenuProc.mel的dagMenuProc过程定义了各种不同物体的右键标记菜单。
比如,在
if (($object == "CubeCompass"))
{
createViewCubeMenuItems($parent);
return;
}
的下面加入:
if(`attributeExists "extNode" $object`){
print ($object+" RMB menu proc calls!\n");
return;

}

重新加载dagMenuProc.mel,新建一个物体,增加一个属性:extNode,类别任意。
再这个物体上使用右键菜单时,就会输出OBJECT NAME RMB menu proc calls!
如果在$parent上加入菜单,就可以显示菜单了。

技术细节:
dagMenuProc并没有出现在文档中,更详细的信息也没法得到,从网上搜索到的信息表明rmb标记菜单是附加在dag属性上的。
Maya's dagMenuProc script controls Right-Mouse-Button clicking on objects in the model viewports.

2008年12月12日星期五

boost::regex匹配序列文件名2

regex默认是perl的语法,但是一些细微的地方和perl的不尽相同。今天就在这上面吃大亏了。

std::string regstr2="("+name+")([0-9]+{"+ia+"})([.]"+ext+")";
boost::regex expression2(regstr2);
就这两句,编译的时候没有问题,一运行就出错,总是说表达式不合法。折腾了半晚上才发现[0-9]+外面要加()才行。
用reggy工具的时候就没有这个问题([0-9]+){3}和[0-9]+{3}是同样的效果,在boost里后者就是不合法的表达式。

boost::regex匹配序列文件名

#include
#include
int main() {
std::string regstr = "(^.*/)([^/]+?)([0-9]+)([.])([^./]+$)";
boost::regex expression(regstr);
std::string testString = "/Users/cobranail/Documents/helghast_sub_ver2.4_mesh006.jpg";
boost::smatch what;
std::string::const_iterator start = testString.begin();
std::string::const_iterator end = testString.end();
while( boost::regex_search(start, end, what, expression) )
{

std::string path(what[1].first, what[1].second);
std::string name(what[2].first, what[2].second);
std::string index(what[3].first, what[3].second);
std::string ext(what[5].first, what[5].second);
std::cout<< "path:" << path.c_str() << std::endl;
std::cout<< "name:" << name.c_str() << std::endl;
std::cout<< "index:" << index.c_str() << std::endl;
std::cout<< "ext:" < start = what[0].second;
}

return 0;
}

可以匹配的文件名:
filename.001.ext
filename001.ext
filename1.ext
file.name.001.ext
file.name001.ext

(^.*/) ---->path
([^/]+?) ---->file
([0-9]+) ---->index
([.]) ------->dot
([^./]+$) ---->ext


参考

2008年8月6日星期三

umf converter

e-motek的umfconv的mac版里destination format那个下拉列表看起来无法选中,其实只是没有显示而已,按下去,拖动鼠标再放开,可以看到格式可以变化。当然不能输入文字的问题估计是无法解决了。

2008年7月4日星期五

ginac另一个符号代数库

http://www.ginac.de/
c++的,大概看了一下演示,效果还不错,使用起来也方便。

2008年5月23日星期五

GSL笔记20080523

最近的一个程序要用到一些矩阵和向量的操作,主程序是用c写的,自己实现一些矩阵的操作倒也不算困难,但是有些运算就不太好实现了,而且质量也难以保证。在google上搜索了一番,于是就发现了GSL(GNU Scientific Library),GNU的好东西还真不少。

很快的翻了一下gsl的手册,写的比较详细,再配合它的例子,一般的使用应该不成问题。
照葫芦画瓢,写了一个求逆矩阵的程序,当然都是数值运算的,好在这次的程序没有符号运算。

#include
#include

int
main (void)
{
double a_data[] = { 0.3, 0, 0, 0,
0, 0.3, 0, 0,
0, 0, 0.3, 0,
0, 0, 0, 0.3 };

double b_data[] = { 1.0, 2.0, 3.0, 4.0 };

gsl_matrix_view m
= gsl_matrix_view_array(a_data, 4, 4);

gsl_vector_view b
= gsl_vector_view_array(b_data, 4);

gsl_vector *x = gsl_vector_alloc (4);
gsl_matrix *mi= gsl_matrix_alloc (4,4);

int s;

gsl_permutation * p = gsl_permutation_alloc (4);

gsl_linalg_LU_decomp (&m.matrix, p, &s);

gsl_linalg_LU_invert (&m.matrix, p, mi);

printf ("inv=\n");
gsl_matrix_fprintf (stdout, mi, "%f");

gsl_permutation_free (p);
return 0;
}


permutation没有查到准确的意思,从手册和例子中的用法猜测,意思大概是行列式前面的符号。
gsl中的线性代数部分在操作矩阵的时候,都是把矩阵分解成某种乘积形式,然后再做运算,上面程序用的是LU分解把m分解成一个下三角阵和上三角阵的乘积,之后再求逆。

2008年5月10日星期六

ADT, queue.h

以前写C的代码的时候,所有的ADT都是自己去实现,那真是一个累啊,无奈自己能力有限,要花费大量的时间来调试ADT部分的代码。终于,某天,在某论坛,看到某高人的一句话…解放了,直接用bsd的queue.h就好了。

能用的还有linux的list.h,不过我在osx上测试没有成功,总是说指针类型不匹配,就算是在linux上也要修改一下,里面已经说了,"don't include kernel headers in userspace"。

2008年5月2日星期五

Duncan提供的几个nCloth的tips

Here are a few points on breakable nCloth:
-If you select verts, edges or faces when making a tearable constraint then it can only tear at those regions, which is more efficient.

-The detach component code internally detachs based on vertices, not edges, so the tearable surface constraint will give "ragged" edges. You can make it more efficient by carefully modelling your own detach edges. Basically initially create your model with all the edges you wish to be breakable being border edges. 

-For large rigid chunks you may wish to use separate objects, each with its own nCloth. Constrain the chunks together with a component to component constraint with glueStrength set and the weld method. Then combine, merge vertex, smooth normals and possibly extrude downstream of the nCloth nodes. This allows you to use rigidity on the nCloth nodes(otherwise you need to use high bend/stretch levels which is less efficient). You can also turn off self collision on the nCloth nodes, because they are internally rigid. If instead you were using one cloth node for all the chunks then you would need self collision so that the chunks could intercollide.

-There is bend stiffness on the constraint node, which can be used for glass shatter sorts of effects. However this requires that you have edge nComponents. If you use standard breakable surface setup with edge components it gets extremely slow to use the constraint bend stiffness for a complex surface. We are currently looking at fixing this problem, as it makes it hard to do rigid shatter effects.

Duncan

2008年4月28日星期一

关于mr framebuffer输出openEXR中的通道

openEXR是ILM设计的一种图像格式,可以比较灵活的存储图像数据,最近的这个demoreel中原始的图像序列都用exr了,唯一的缺点就是体积太大,一张640*360的rgba 4*32bit的图竟然要3.5MB的空间。
这里要说的是exr的另一个问题,在maya中用输出exr格式的图像时,sw渲染器不支持exr,这里说的是mr。如果在mr的framebuffer中设置成输入rgba,那么在生成的exr文件中,rgba通道都会用A B G R的名字表示。但是,如果要单独输出motion或者alpha的话,通道的名字就成了mi_buffer_###,###就是每一帧的序列号,也就是说每一帧的通道名称都是不一样的。
这样,在合成的时候就有点麻烦了。nuke的reader节点可以正常的预览的这种exr序列,创建reader节点之后,它是按通道来读取exr序列的,每都一帧,都会创建一个新的通道,可viewer节点却是按照通道来显示的,还有channel组里的节点也都是如此,这样一来每一帧改变一次通道。
这个问题解决起来也简单,只要该一下exr文件通道的名字即可,以framebuffer输出motion向量为例。

用一个16进制编辑器打开一个exr文件,可以看到从offset:0x1CL开始,就是通道和分量的名字,这里我们只需要修改0x26L开始的帧编号,只要把整个exr序列中的帧编号都替换成一个固定的字符串即可。我写了一个简单的程序来完成这个工作。

#include
#include

int main(int argc, char *argv[]){
char *str="mt0";

FILE *fp;
fp=fopen(argv[1],"rb+");

fseek(fp,0x26L,0);
fwrite(str,sizeof(char),3,fp);

fseek(fp,0x46L,0);
fwrite(str,sizeof(char),3,fp);

fseek(fp,0x66L,0);
fwrite(str,sizeof(char),3,fp);

fclose(fp);
return 0;

}


下面是修改后的exr文件头,我把帧编号都改成了mt0。

2008年2月13日星期三

maya fluid cache笔记1



FOR4 CACH <------------ This exists for all disk cache
. STIM startTime (TanimTime)
. ETIM endTime (TanimTime)
. TYPE isOverSampling (Tboolean)
. RATE samplingRate (TuInt32)
// block #1
FOR4 FLUD
.TIME currentTime (TanimTime)
.WRES widthRes (Tint32)
.HRES heightRes (Tint32)
.DRES depthRes (Tint32)
.NUMD numDensVal (Tint32)
.DENS densities (Tfloats)
.NMVX numVelX (Tint32)
.NMVY numVelY (Tint32)
.NMVZ numVelZ (Tint32)
.VELX xVelocities (Tfloats)
.VELY yVelocities (Tfloats)
.VELZ zVelocities (Tfloats)
.NUMT numTemperature (Tinit32)
.TEMP temperatures (Tfloats)
.NUMR numReaction (Tinit32)
.REAC reactions (Tfloats)
.NUMC numColors (Tint32)
.COLR RedColors (Tfloats)
.COLB BlueColors (Tfloats)
.COLG GreenColors (Tfloats)
.NUMU numTexCoord (Tint32)
.TEXU uCoords (Tfloats)
.TEXV vCoords (Tfloats)
.TEXW wCoords (Tfloats)
// block #2
FOR4 FLUD
........
Note:
TanimTime: an unsigned int, units are 1/6000 second
Tfloats: an array of floats, the count is specified by the
preceding "num" tag.

以上引用自maya文档。

下面是一个4x4的2d流体的cache,只有density部分。


用STIM作为例子来说明,53 54 49 4D 00 00 00 04,是STIM段的标识,而后面的00 00 00 FA才是SITM段的数据。00 00 00 FA是一个无符号整数,作为一个整数读入之后,是FA 00 00 00的顺序,这与本意是相反的(开始我以为是mac才这样,后来发现在linux上也是如此)。在读入之后,需要直接通过内存地址修改数据的顺序。
后面的DENS数据段里的42 C8 00 00,在内存中,应该是(低地址)00 00 C8 42(高地址)的顺序。

2008年1月15日星期二

Dryad



http://dryad.stanford.edu/index.php

当斯坦福大学计算机科学家Vladlen Koltun计划建立一个更完美的虚拟世界时,他选择了树——数以百万计,现在他想把它们送给别人种植。

ps:输出的obj有问题,不如在软件中的好看,maya打开obj后出错,blender打开后树的模型很粗糙。