From 157d1205a42b07042d8abdb590034940b68f0b12 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 3 Oct 2010 14:16:27 +0000 Subject: added len_squared_v2v2, use instead of len_v3v3 for font handle tests, also fixed some warnings. --- source/blender/blenlib/BLI_math_vector.h | 1 + source/blender/blenlib/intern/freetypefont.c | 14 +++++++------- source/blender/blenlib/intern/math_vector_inline.c | 12 ++++++++++-- source/blender/editors/space_image/image_draw.c | 4 ++++ 4 files changed, 22 insertions(+), 9 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index 215ddf2f2d9..b160097a33d 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -95,6 +95,7 @@ MINLINE void star_m3_v3(float R[3][3],float a[3]); MINLINE float len_v2(const float a[2]); MINLINE float len_v2v2(const float a[2], const float b[2]); +MINLINE float len_squared_v2v2(const float a[3], const float b[3]); MINLINE float len_v3(const float a[3]); MINLINE float len_v3v3(const float a[3], const float b[3]); MINLINE float len_squared_v3v3(const float a[3], const float b[3]); diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c index 6d6abc88999..fc41839c303 100644 --- a/source/blender/blenlib/intern/freetypefont.c +++ b/source/blender/blenlib/intern/freetypefont.c @@ -252,15 +252,15 @@ static void freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *vf } // get the handles that are aligned, tricky... - // DistVL2Dfl, check if the three beztriple points are on one line - // VecLenf, see if there's a distance between the three points - // VecLenf again, to check the angle between the handles + // dist_to_line_v2, check if the three beztriple points are on one line + // len_squared_v2v2, see if there's a distance between the three points + // len_squared_v2v2 again, to check the angle between the handles // finally, check if one of them is a vector handle if((dist_to_line_v2(bezt->vec[0],bezt->vec[1],bezt->vec[2]) < 0.001) && - (len_v3v3(bezt->vec[0], bezt->vec[1]) > 0.0001) && - (len_v3v3(bezt->vec[1], bezt->vec[2]) > 0.0001) && - (len_v3v3(bezt->vec[0], bezt->vec[2]) > 0.0002) && - (len_v3v3(bezt->vec[0], bezt->vec[2]) > MAX2(len_v3v3(bezt->vec[0], bezt->vec[1]), len_v3v3(bezt->vec[1], bezt->vec[2]))) && + (len_squared_v2v2(bezt->vec[0], bezt->vec[1]) > 0.0001*0.0001) && + (len_squared_v2v2(bezt->vec[1], bezt->vec[2]) > 0.0001*0.0001) && + (len_squared_v2v2(bezt->vec[0], bezt->vec[2]) > 0.0002*0.0001) && + (len_squared_v2v2(bezt->vec[0], bezt->vec[2]) > MAX2(len_squared_v2v2(bezt->vec[0], bezt->vec[1]), len_squared_v2v2(bezt->vec[1], bezt->vec[2]))) && bezt->h1 != HD_VECT && bezt->h2 != HD_VECT) { bezt->h1= bezt->h2= HD_ALIGN; diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index 84d96d1d22a..2f75fcead79 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -302,7 +302,7 @@ MINLINE void star_m3_v3(float mat[][3], float *vec) MINLINE float len_v2(const float v[2]) { - return (float)sqrt(v[0]*v[0] + v[1]*v[1]); + return (float)sqrtf(v[0]*v[0] + v[1]*v[1]); } MINLINE float len_v2v2(const float v1[2], const float v2[2]) @@ -311,7 +311,7 @@ MINLINE float len_v2v2(const float v1[2], const float v2[2]) x = v1[0]-v2[0]; y = v1[1]-v2[1]; - return (float)sqrt(x*x+y*y); + return (float)sqrtf(x*x+y*y); } MINLINE float len_v3(const float a[3]) @@ -319,6 +319,14 @@ MINLINE float len_v3(const float a[3]) return sqrtf(dot_v3v3(a, a)); } +MINLINE float len_squared_v2v2(const float a[3], const float b[3]) +{ + float d[2]; + + sub_v2_v2v2(d, b, a); + return dot_v2v2(d, d); +} + MINLINE float len_v3v3(const float a[3], const float b[3]) { float d[3]; diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index 6a77d4da067..f29d1bc033f 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -49,6 +49,10 @@ #include "BKE_image.h" #include "BKE_paint.h" +#ifdef WITH_LCMS +#include "BKE_colortools.h" +#endif + #include "BIF_gl.h" #include "BIF_glutil.h" -- cgit v1.2.3 From b0b5db57daf9dd5804523aa3f3d4688004a30d9a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 3 Oct 2010 16:16:00 +0000 Subject: build systems have been updated, remove use of ~/.blender/ directly, ~/.blender/*version*/ instead. --- source/blender/blenlib/intern/path_util.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index 5c9086cfb90..d388586bf66 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -873,10 +873,6 @@ static int get_path_local(char *targetpath, char *folder_name, char *subfolder_n if(test_path(targetpath, bprogdir, blender_version_decimal(), relfolder)) return 1; - /* try ./.blender/folder_name -- DEPRECATED, need to update build systems */ - if(test_path(targetpath, bprogdir, ".blender", relfolder)) - return 1; - return 0; } -- cgit v1.2.3 From ab8aa13b829c9a49b60294883613d6b4bf33f835 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 3 Oct 2010 20:00:22 +0000 Subject: bugfix [#24087] Blender can not install add-ons unless running with root priviledges now addon path is created using the same path functions and selecting where to save the startup.blend also made some minor changes to path handling funcs. --- source/blender/blenlib/BLI_path_util.h | 1 + source/blender/blenlib/intern/path_util.c | 18 ++++---- .../blender/python/generic/bpy_internal_import.c | 4 +- .../blender/python/generic/bpy_internal_import.h | 4 +- source/blender/python/intern/bpy.c | 53 ++++++++++++++++++++-- source/blender/python/intern/bpy_interface.c | 4 +- source/blender/windowmanager/intern/wm_files.c | 11 +++-- 7 files changed, 72 insertions(+), 23 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h index f01e1a25d8a..b9a4468fe57 100644 --- a/source/blender/blenlib/BLI_path_util.h +++ b/source/blender/blenlib/BLI_path_util.h @@ -44,6 +44,7 @@ char *BLI_getDefaultDocumentFolder(void); char *BLI_get_folder(int folder_id, char *subfolder); char *BLI_get_folder_create(int folder_id, char *subfolder); +char *BLI_get_user_folder_notest(int folder_id, char *subfolder); /* folder_id */ diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index d388586bf66..fd69b7233de 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -477,7 +477,7 @@ int BLI_parent_dir(char *path) static char *parent_dir="../"; #endif char tmp[FILE_MAXDIR+FILE_MAXFILE+4]; - BLI_strncpy(tmp, path, sizeof(tmp)); + BLI_strncpy(tmp, path, sizeof(tmp)-4); BLI_add_slash(tmp); strcat(tmp, parent_dir); BLI_cleanup_dir(NULL, tmp); @@ -839,8 +839,6 @@ static int get_path_local(char *targetpath, char *folder_name, char *subfolder_n char bprogdir[FILE_MAX]; char relfolder[FILE_MAX]; char cwd[FILE_MAX]; - char *s; - int i; #ifdef PATH_DEBUG2 printf("get_path_local...\n"); @@ -853,9 +851,7 @@ static int get_path_local(char *targetpath, char *folder_name, char *subfolder_n } /* use argv[0] (bprogname) to get the path to the executable */ - s = BLI_last_slash(bprogname); - i = s - bprogname + 1; - BLI_strncpy(bprogdir, bprogname, i); + BLI_split_dirfile(bprogname, bprogdir, NULL); /* try EXECUTABLE_DIR/folder_name */ if(test_path(targetpath, bprogdir, "", relfolder)) @@ -1024,7 +1020,7 @@ char *BLI_get_folder(int folder_id, char *subfolder) return path; } -static char *BLI_get_user_folder_notest(int folder_id, char *subfolder) +char *BLI_get_user_folder_notest(int folder_id, char *subfolder) { static char path[FILE_MAX] = ""; @@ -1038,6 +1034,9 @@ static char *BLI_get_user_folder_notest(int folder_id, char *subfolder) case BLENDER_USER_AUTOSAVE: get_path_user(path, "autosave", subfolder, "BLENDER_USER_AUTOSAVE"); break; + case BLENDER_USER_SCRIPTS: + get_path_user(path, "scripts", subfolder, "BLENDER_USER_SCRIPTS"); + break; } if ('\0' == path[0]) { return NULL; @@ -1050,7 +1049,7 @@ char *BLI_get_folder_create(int folder_id, char *subfolder) char *path; /* only for user folders */ - if (!ELEM3(folder_id, BLENDER_USER_DATAFILES, BLENDER_USER_CONFIG, BLENDER_USER_AUTOSAVE)) + if (!ELEM4(folder_id, BLENDER_USER_DATAFILES, BLENDER_USER_CONFIG, BLENDER_USER_SCRIPTS, BLENDER_USER_AUTOSAVE)) return NULL; path = BLI_get_folder(folder_id, subfolder); @@ -1205,8 +1204,7 @@ void BLI_make_file_string(const char *relabase, char *string, const char *dir, /* Get the file name, chop everything past the last slash (ie. the filename) */ strcpy(string, relabase); - lslash= (strrchr(string, '/')>strrchr(string, '\\'))?strrchr(string, '/'):strrchr(string, '\\'); - + lslash= BLI_last_slash(string); if(lslash) *(lslash+1)= 0; dir+=2; /* Skip over the relative reference */ diff --git a/source/blender/python/generic/bpy_internal_import.c b/source/blender/python/generic/bpy_internal_import.c index 11f8ff49ffe..394c388394a 100644 --- a/source/blender/python/generic/bpy_internal_import.c +++ b/source/blender/python/generic/bpy_internal_import.c @@ -281,8 +281,8 @@ static PyObject *blender_reload( PyObject * self, PyObject * module ) return newmodule; } -PyMethodDef bpy_import_meth[] = { {"bpy_import_meth", (PyCFunction)blender_import, METH_VARARGS | METH_KEYWORDS, "blenders import"} }; -PyMethodDef bpy_reload_meth[] = { {"bpy_reload_meth", (PyCFunction)blender_reload, METH_O, "blenders reload"} }; +PyMethodDef bpy_import_meth = {"bpy_import_meth", (PyCFunction)blender_import, METH_VARARGS | METH_KEYWORDS, "blenders import"}; +PyMethodDef bpy_reload_meth = {"bpy_reload_meth", (PyCFunction)blender_reload, METH_O, "blenders reload"}; /* Clear user modules. diff --git a/source/blender/python/generic/bpy_internal_import.h b/source/blender/python/generic/bpy_internal_import.h index 09e1fa629d3..f191ab22651 100644 --- a/source/blender/python/generic/bpy_internal_import.h +++ b/source/blender/python/generic/bpy_internal_import.h @@ -53,8 +53,8 @@ PyObject* bpy_text_reimport( PyObject *module, int *found ); void bpy_text_filename_get(char *fn, struct Text *text); -extern PyMethodDef bpy_import_meth[]; -extern PyMethodDef bpy_reload_meth[]; +extern PyMethodDef bpy_import_meth; +extern PyMethodDef bpy_reload_meth; /* The game engine has its own Main struct, if this is set search this rather then G.main */ struct Main *bpy_import_main_get(void); diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c index 12a5221f76e..69b5faceca0 100644 --- a/source/blender/python/intern/bpy.c +++ b/source/blender/python/intern/bpy.c @@ -112,8 +112,52 @@ static PyObject *bpy_blend_paths(PyObject * self, PyObject *args, PyObject *kw) return list; } -static PyMethodDef meth_bpy_script_paths[] = {{ "script_paths", (PyCFunction)bpy_script_paths, METH_NOARGS, bpy_script_paths_doc}}; -static PyMethodDef meth_bpy_blend_paths[] = {{ "blend_paths", (PyCFunction)bpy_blend_paths, METH_VARARGS|METH_KEYWORDS, bpy_blend_paths_doc}}; + +static char bpy_user_resource_doc[] = +".. function:: user_resource(type, subdir)\n" +"\n" +" Returns a list of paths to external files referenced by the loaded .blend file.\n" +"\n" +" :arg type: Resource type in ['DATAFILES', 'CONFIG', 'SCRIPTS', 'AUTOSAVE'].\n" +" :type type: string\n" +" :arg subdir: Optional subdirectory.\n" +" :type subdir: string\n" +" :return: a path.\n" +" :rtype: string\n"; +static PyObject *bpy_user_resource(PyObject * self, PyObject *args, PyObject *kw) +{ + char *type; + char *subdir= NULL; + int folder_id; + static char *kwlist[] = {"type", "subdir", NULL}; + + char *path; + + if (!PyArg_ParseTupleAndKeywords(args, kw, "s|s:user_resource", kwlist, &type, &subdir)) + return NULL; + + /* stupid string compare */ + if (!strcmp(type, "DATAFILES")) folder_id= BLENDER_USER_DATAFILES; + else if(!strcmp(type, "CONFIG")) folder_id= BLENDER_USER_CONFIG; + else if(!strcmp(type, "SCRIPTS")) folder_id= BLENDER_USER_SCRIPTS; + else if(!strcmp(type, "AUTOSAVE")) folder_id= BLENDER_USER_AUTOSAVE; + else { + PyErr_SetString(PyExc_ValueError, "invalid resource argument"); + return NULL; + } + + /* same logic as BLI_get_folder_create(), but best leave it up to the script author to create */ + path= BLI_get_folder(folder_id, subdir); + + if (!path) + path = BLI_get_user_folder_notest(folder_id, subdir); + + return PyUnicode_FromString(path ? path : ""); +} + +static PyMethodDef meth_bpy_script_paths = {"script_paths", (PyCFunction)bpy_script_paths, METH_NOARGS, bpy_script_paths_doc}; +static PyMethodDef meth_bpy_blend_paths = {"blend_paths", (PyCFunction)bpy_blend_paths, METH_VARARGS|METH_KEYWORDS, bpy_blend_paths_doc}; +static PyMethodDef meth_bpy_user_resource = {"user_resource", (PyCFunction)bpy_user_resource, METH_VARARGS|METH_KEYWORDS, bpy_user_resource_doc}; static void bpy_import_test(char *modname) { @@ -186,8 +230,9 @@ void BPy_init_modules( void ) PyModule_AddObject(mod, "context", (PyObject *)bpy_context_module); /* utility func's that have nowhere else to go */ - PyModule_AddObject(mod, meth_bpy_script_paths->ml_name, (PyObject *)PyCFunction_New(meth_bpy_script_paths, NULL)); - PyModule_AddObject(mod, meth_bpy_blend_paths->ml_name, (PyObject *)PyCFunction_New(meth_bpy_blend_paths, NULL)); + PyModule_AddObject(mod, meth_bpy_script_paths.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_script_paths, NULL)); + PyModule_AddObject(mod, meth_bpy_blend_paths.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_blend_paths, NULL)); + PyModule_AddObject(mod, meth_bpy_user_resource.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_user_resource, NULL)); /* add our own modules dir, this is a python package */ bpy_import_test("bpy"); diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 6aaac3cd0e8..b905fb3729e 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -248,8 +248,8 @@ void BPY_start_python( int argc, char **argv ) //PyObject *m = PyImport_AddModule("__builtin__"); //PyObject *d = PyModule_GetDict(m); PyObject *d = PyEval_GetBuiltins( ); - PyDict_SetItemString(d, "reload", item=PyCFunction_New(bpy_reload_meth, NULL)); Py_DECREF(item); - PyDict_SetItemString(d, "__import__", item=PyCFunction_New(bpy_import_meth, NULL)); Py_DECREF(item); + PyDict_SetItemString(d, "reload", item=PyCFunction_New(&bpy_reload_meth, NULL)); Py_DECREF(item); + PyDict_SetItemString(d, "__import__", item=PyCFunction_New(&bpy_import_meth, NULL)); Py_DECREF(item); } pyrna_alloc_types(); diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 33564834bcb..67decd6292e 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -681,15 +681,20 @@ int WM_write_homefile(bContext *C, wmOperator *op) wm_window_close(C, wm, win); BLI_make_file_string("/", tstr, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_STARTUP_FILE); - printf("trying to save homefile at %s \n", tstr); + printf("trying to save homefile at %s ", tstr); /* force save as regular blend file */ fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_LOCK | G_FILE_SIGN); - BLO_write_file(CTX_data_main(C), tstr, fileflags, op->reports, NULL); + if(BLO_write_file(CTX_data_main(C), tstr, fileflags, op->reports, NULL) == 0) { + printf("fail\n"); + return OPERATOR_CANCELLED; + } + printf("ok\n"); + G.save_over= 0; - + return OPERATOR_FINISHED; } -- cgit v1.2.3 From 02d0084db9c5573b9d5fafd4eb10c87aab34df8d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 3 Oct 2010 21:13:52 +0000 Subject: changes to path searching - don't search CWD/foldername anymore, only CWD/2.54/foldername, since this is the new default build systems use. - local source paths (./release/scripts) are now treated as system path, otherwise when this is used you cant test ~/.blender/2.54/scripts at the same time. --- source/blender/blenlib/intern/path_util.c | 43 +++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 14 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index fd69b7233de..23972c64ee1 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -838,7 +838,6 @@ static int get_path_local(char *targetpath, char *folder_name, char *subfolder_n extern char bprogname[]; /* argv[0] from creator.c */ char bprogdir[FILE_MAX]; char relfolder[FILE_MAX]; - char cwd[FILE_MAX]; #ifdef PATH_DEBUG2 printf("get_path_local...\n"); @@ -853,19 +852,7 @@ static int get_path_local(char *targetpath, char *folder_name, char *subfolder_n /* use argv[0] (bprogname) to get the path to the executable */ BLI_split_dirfile(bprogname, bprogdir, NULL); - /* try EXECUTABLE_DIR/folder_name */ - if(test_path(targetpath, bprogdir, "", relfolder)) - return 1; - - /* try CWD/release/folder_name */ - if(test_path(targetpath, BLI_getwdN(cwd), "release", relfolder)) - return 1; - - /* try EXECUTABLE_DIR/release/folder_name */ - if(test_path(targetpath, bprogdir, "release", relfolder)) - return 1; - - /* try EXECUTABLE_DIR/2.5/folder_name - new default directory for local blender installed files */ + /* try EXECUTABLE_DIR/2.5x/folder_name - new default directory for local blender installed files */ if(test_path(targetpath, bprogdir, blender_version_decimal(), relfolder)) return 1; @@ -914,6 +901,34 @@ static int get_path_system(char *targetpath, char *folder_name, char *subfolder_ char system_path[FILE_MAX]; const char *system_base_path; + + /* first allow developer only overrides to the system path + * these are only used when running blender from source */ + extern char bprogname[]; /* argv[0] from creator.c */ + char cwd[FILE_MAX]; + char relfolder[FILE_MAX]; + char bprogdir[FILE_MAX]; + + /* use argv[0] (bprogname) to get the path to the executable */ + BLI_split_dirfile(bprogname, bprogdir, NULL); + + if (subfolder_name) { + BLI_join_dirfile(relfolder, folder_name, subfolder_name); + } else { + BLI_strncpy(relfolder, folder_name, FILE_MAX); + } + + /* try CWD/release/folder_name */ + if(test_path(targetpath, BLI_getwdN(cwd), "release", relfolder)) + return 1; + + /* try EXECUTABLE_DIR/release/folder_name */ + if(test_path(targetpath, bprogdir, "release", relfolder)) + return 1; + /* end developer overrides */ + + + system_path[0] = '\0'; if (test_env_path(system_path, envvar)) { -- cgit v1.2.3 From 874ffaca7b70497d6d523fb6fa1457987e403a5d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 3 Oct 2010 23:29:43 +0000 Subject: typo in function prefix. --- source/blender/python/generic/IDProp.c | 6 +++--- source/blender/python/generic/py_capi_utils.c | 2 +- source/blender/python/generic/py_capi_utils.h | 2 +- source/blender/python/intern/bpy_rna.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'source/blender') diff --git a/source/blender/python/generic/IDProp.c b/source/blender/python/generic/IDProp.c index 2a07ab3bc90..9d865b1c63e 100644 --- a/source/blender/python/generic/IDProp.c +++ b/source/blender/python/generic/IDProp.c @@ -34,7 +34,7 @@ #endif PyObject * PyC_UnicodeFromByte(const char *str); -const char * PuC_UnicodeAsByte(PyObject *py_str, PyObject **coerce); /* coerce must be NULL */ +const char * PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce); /* coerce must be NULL */ /*** Function to wrap ID properties ***/ PyObject *BPy_Wrap_IDProperty(ID *id, IDProperty *prop, IDProperty *parent); @@ -123,7 +123,7 @@ int BPy_IDGroup_SetData(BPy_IDProperty *self, IDProperty *prop, PyObject *value) int alloc_len; PyObject *value_coerce= NULL; - st= (char *)PuC_UnicodeAsByte(value, &value_coerce); + st= (char *)PyC_UnicodeAsByte(value, &value_coerce); alloc_len= strlen(st) + 1; st = _PyUnicode_AsString(value); @@ -311,7 +311,7 @@ char *BPy_IDProperty_Map_ValidateAndCreate(char *name, IDProperty *group, PyObje } else if (PyUnicode_Check(ob)) { #ifdef USE_STRING_COERCE PyObject *value_coerce= NULL; - val.str = (char *)PuC_UnicodeAsByte(ob, &value_coerce); + val.str = (char *)PyC_UnicodeAsByte(ob, &value_coerce); prop = IDP_New(IDP_STRING, val, name); Py_XDECREF(value_coerce); #else diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c index d59624b54ab..6544523079d 100644 --- a/source/blender/python/generic/py_capi_utils.c +++ b/source/blender/python/generic/py_capi_utils.c @@ -217,7 +217,7 @@ error_cleanup: /* string conversion, escape non-unicode chars, coerce must be set to NULL */ -const char *PuC_UnicodeAsByte(PyObject *py_str, PyObject **coerce) +const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce) { char *result; diff --git a/source/blender/python/generic/py_capi_utils.h b/source/blender/python/generic/py_capi_utils.h index b378f7a5a34..0544697ab68 100644 --- a/source/blender/python/generic/py_capi_utils.h +++ b/source/blender/python/generic/py_capi_utils.h @@ -34,7 +34,7 @@ int PyC_AsArray(void *array, PyObject *value, int length, PyTypeObject *type, /* follow http://www.python.org/dev/peps/pep-0383/ */ PyObject * PyC_UnicodeFromByte(const char *str); -const char * PuC_UnicodeAsByte(PyObject *py_str, PyObject **coerce); /* coerce must be NULL */ +const char * PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce); /* coerce must be NULL */ /* name namespace function for bpy & bge */ PyObject * PyC_DefaultNameSpace(const char *filename); diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 238201c7cf0..93106d5400f 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -1012,7 +1012,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, ParameterList *p PyObject *value_coerce= NULL; int subtype= RNA_property_subtype(prop); if(ELEM3(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) { - param= PuC_UnicodeAsByte(value, &value_coerce); + param= PyC_UnicodeAsByte(value, &value_coerce); } else { param= _PyUnicode_AsString(value); -- cgit v1.2.3 From 314121ee65a5d2aadb9be56afcc31201e0eda596 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 4 Oct 2010 01:18:47 +0000 Subject: - use own string conversion function over PyUnicode_FromString when converting the argv - report errors when files dont load when given from the command line but not running in background mode. --- source/blender/blenkernel/intern/report.c | 1 + source/blender/python/intern/bpy_interface.c | 19 ++----------------- 2 files changed, 3 insertions(+), 17 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c index 3773757f5d5..f69547fd1da 100644 --- a/source/blender/blenkernel/intern/report.c +++ b/source/blender/blenkernel/intern/report.c @@ -127,6 +127,7 @@ void BKE_reportf(ReportList *reports, ReportType type, const char *format, ...) va_start(args, format); vprintf(format, args); va_end(args); + fprintf(stdout, "\n"); /* otherise each report needs to include a \n */ fflush(stdout); /* this ensures the message is printed before a crash */ } diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index b905fb3729e..bc79ba94756 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -213,25 +213,10 @@ void BPY_start_python( int argc, char **argv ) /* sigh, why do python guys not have a char** version anymore? :( */ { int i; -#if 0 PyObject *py_argv= PyList_New(argc); for (i=0; i Date: Mon, 4 Oct 2010 03:38:37 +0000 Subject: COLLADA exporter fix: do not create a duplicate if an object has NULL materials linked along with normal materials. --- source/blender/collada/DocumentExporter.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'source/blender') diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp index c2d937f3d43..d10fa4ca94c 100644 --- a/source/blender/collada/DocumentExporter.cpp +++ b/source/blender/collada/DocumentExporter.cpp @@ -497,13 +497,11 @@ public: // XXX slow if (ob->totcol) { for(int a = 0; a < ob->totcol; a++) { - // account for NULL materials, this should not normally happen? - Material *ma = give_current_material(ob, a + 1); - createPolylist(ma != NULL, a, has_uvs, has_color, ob, geom_id, norind); + createPolylist(a, has_uvs, has_color, ob, geom_id, norind); } } else { - createPolylist(false, 0, has_uvs, has_color, ob, geom_id, norind); + createPolylist(0, has_uvs, has_color, ob, geom_id, norind); } closeMesh(); @@ -515,8 +513,7 @@ public: } // powerful because it handles both cases when there is material and when there's not - void createPolylist(bool has_material, - int material_index, + void createPolylist(int material_index, bool has_uvs, bool has_color, Object *ob, @@ -536,7 +533,7 @@ public: for (i = 0; i < totfaces; i++) { MFace *f = &mfaces[i]; - if ((has_material && f->mat_nr == material_index) || !has_material) { + if (f->mat_nr == material_index) { faces_in_polylist++; if (f->v4 == 0) { vcount_list.push_back(3); @@ -549,17 +546,18 @@ public: // no faces using this material if (faces_in_polylist == 0) { + fprintf(stderr, "%s: no faces use material %d\n", id_name(ob).c_str(), material_index); return; } - Material *ma = has_material ? give_current_material(ob, material_index + 1) : NULL; + Material *ma = ob->totcol ? give_current_material(ob, material_index + 1) : NULL; COLLADASW::Polylist polylist(mSW); // sets count attribute in polylist.setCount(faces_in_polylist); // sets material name - if (has_material) { + if (ma) { polylist.setMaterial(translate_id(id_name(ma))); } @@ -603,7 +601,7 @@ public: for (i = 0; i < totfaces; i++) { MFace *f = &mfaces[i]; - if ((has_material && f->mat_nr == material_index) || !has_material) { + if (f->mat_nr == material_index) { unsigned int *v = &f->v1; unsigned int *n = &norind[i].v1; -- cgit v1.2.3 From 636e555ec2aa862d23470c8c2cd0d48cb1b9125d Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Mon, 4 Oct 2010 08:48:50 +0000 Subject: Fix for [#24118] Hair particles can not be edited * Own mistake from a previous fix. --- source/blender/blenkernel/intern/pointcache.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 784f6e40706..e1006cd99cd 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -1015,8 +1015,9 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int dup if(ELEM(psys->part->phystype, PART_PHYS_NO, PART_PHYS_KEYED)) continue; - if(psys->part->type == PART_HAIR && (psys->flag & PSYS_HAIR_DYNAMICS)==0) - continue; + /* hair needs to be included in id-list for cache edit mode to work */ + /* if(psys->part->type == PART_HAIR && (psys->flag & PSYS_HAIR_DYNAMICS)==0) */ + /* continue; */ if(psys->part->type == PART_FLUID) continue; -- cgit v1.2.3 From a6d62bf0db09ae2759fd45abb3af563fefc13690 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 4 Oct 2010 10:06:18 +0000 Subject: Recalc knots when toggling nurb cyclic flags --- source/blender/makesrna/intern/rna_curve.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'source/blender') diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index 37be1d89d30..50c21640554 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -399,12 +399,24 @@ void rna_Curve_body_set(PointerRNA *ptr, const char *value) BLI_strncpy(cu->str, value, len+1); } -static void rna_Nurb_update_handle_data(Main *bmain, Scene *scene, PointerRNA *ptr) +static void rna_Nurb_update_cyclic_u(Main *bmain, Scene *scene, PointerRNA *ptr) { Nurb *nu= (Nurb*)ptr->data; - if(nu->type == CU_BEZIER) + if(nu->type == CU_BEZIER) { calchandlesNurb(nu); + } else { + nurbs_knot_calc_u(nu); + } + + rna_Curve_update_data(bmain, scene, ptr); +} + +static void rna_Nurb_update_cyclic_v(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + Nurb *nu= (Nurb*)ptr->data; + + nurbs_knot_calc_v(nu); rna_Curve_update_data(bmain, scene, ptr); } @@ -1356,12 +1368,12 @@ static void rna_def_curve_nurb(BlenderRNA *brna) prop= RNA_def_property(srna, "use_cyclic_u", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flagu", CU_NURB_CYCLIC); RNA_def_property_ui_text(prop, "Cyclic U", "Make this curve or surface a closed loop in the U direction"); - RNA_def_property_update(prop, 0, "rna_Nurb_update_handle_data"); /* only needed for cyclic_u because cyclic_v cant do bezier */ + RNA_def_property_update(prop, 0, "rna_Nurb_update_cyclic_u"); prop= RNA_def_property(srna, "use_cyclic_v", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flagv", CU_NURB_CYCLIC); RNA_def_property_ui_text(prop, "Cyclic V", "Make this surface a closed loop in the V direction"); - RNA_def_property_update(prop, 0, "rna_Curve_update_data"); + RNA_def_property_update(prop, 0, "rna_Nurb_update_cyclic_u"); /* Note, endpoint and bezier flags should never be on at the same time! */ -- cgit v1.2.3 From c76d339b6cb121e3dc31dc7f032e8a0cb3ad9e90 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 4 Oct 2010 12:02:18 +0000 Subject: fix for copy in the console (wasnt taking the prompt into account) --- .../blender/editors/space_console/console_draw.c | 32 ++++++++++++++-------- .../blender/editors/space_console/console_intern.h | 3 ++ source/blender/editors/space_console/console_ops.c | 11 ++++++-- 3 files changed, 32 insertions(+), 14 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c index d1fa4e17e6f..d5ffb34b3a2 100644 --- a/source/blender/editors/space_console/console_draw.c +++ b/source/blender/editors/space_console/console_draw.c @@ -286,6 +286,24 @@ static int console_draw_string(ConsoleDrawContext *cdc, char *str, int str_len, #undef STEP_SEL } +void console_scrollback_prompt_begin(struct SpaceConsole *sc, ConsoleLine *cl_dummy) +{ + /* fake the edit line being in the scroll buffer */ + ConsoleLine *cl= sc->history.last; + cl_dummy->type= CONSOLE_LINE_INPUT; + cl_dummy->len= cl_dummy->len_alloc= strlen(sc->prompt) + cl->len; + cl_dummy->len_alloc= cl_dummy->len + 1; + cl_dummy->line= MEM_mallocN(cl_dummy->len_alloc, "cl_dummy"); + memcpy(cl_dummy->line, sc->prompt, (cl_dummy->len_alloc - cl->len)); + memcpy(cl_dummy->line + ((cl_dummy->len_alloc - cl->len)) - 1, cl->line, cl->len + 1); + BLI_addtail(&sc->scrollback, cl_dummy); +} +void console_scrollback_prompt_end(struct SpaceConsole *sc, ConsoleLine *cl_dummy) +{ + MEM_freeN(cl_dummy->line); + BLI_remlink(&sc->scrollback, cl_dummy); +} + #define CONSOLE_DRAW_MARGIN 4 #define CONSOLE_DRAW_SCROLL 16 @@ -349,15 +367,7 @@ static int console_text_main__internal(struct SpaceConsole *sc, struct ARegion * xy[0]= x_orig; /* remove prompt offset */ } - /* fake the edit line being in the scroll buffer */ - cl_dummy.type= CONSOLE_LINE_INPUT; - cl_dummy.len= cl_dummy.len_alloc= prompt_len + cl->len; - cl_dummy.len_alloc= cl_dummy.len + 1; - cl_dummy.line= MEM_mallocN(cl_dummy.len_alloc, "cl_dummy"); - memcpy(cl_dummy.line, sc->prompt, (cl_dummy.len_alloc - cl->len)); - memcpy(cl_dummy.line + ((cl_dummy.len_alloc - cl->len)) - 1, cl->line, cl->len + 1); - BLI_addtail(&sc->scrollback, &cl_dummy); - + console_scrollback_prompt_begin(sc, &cl_dummy); for(cl= sc->scrollback.last; cl; cl= cl->prev) { y_prev= xy[1]; @@ -378,9 +388,7 @@ static int console_text_main__internal(struct SpaceConsole *sc, struct ARegion * } } - /* temp line end */ - MEM_freeN(cl_dummy.line); - BLI_remlink(&sc->scrollback, &cl_dummy); + console_scrollback_prompt_end(sc, &cl_dummy); } else { Report *report; diff --git a/source/blender/editors/space_console/console_intern.h b/source/blender/editors/space_console/console_intern.h index c74d39f25e3..0e2c35bcf83 100644 --- a/source/blender/editors/space_console/console_intern.h +++ b/source/blender/editors/space_console/console_intern.h @@ -41,6 +41,9 @@ int console_text_height(struct SpaceConsole *sc, struct ARegion *ar, struct Repo void *console_text_pick(struct SpaceConsole *sc, struct ARegion *ar, struct ReportList *reports, int mouse_y); /* needed for selection */ int console_char_pick(struct SpaceConsole *sc, struct ARegion *ar, ReportList *reports, int mval[2]); +void console_scrollback_prompt_begin(struct SpaceConsole *sc, ConsoleLine *cl_dummy); +void console_scrollback_prompt_end(struct SpaceConsole *sc, ConsoleLine *cl_dummy); + /* console_ops.c */ void console_history_free(SpaceConsole *sc, ConsoleLine *cl); void console_scrollback_free(SpaceConsole *sc, ConsoleLine *cl); diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c index a49581cb417..8ececa22163 100644 --- a/source/blender/editors/space_console/console_ops.c +++ b/source/blender/editors/space_console/console_ops.c @@ -705,6 +705,8 @@ static int copy_exec(bContext *C, wmOperator *op) int sel[2]; int offset= 0; + ConsoleLine cl_dummy= {0}; + #if 0 /* copy whole file */ for(cl= sc->scrollback.first; cl; cl= cl->next) { @@ -716,14 +718,16 @@ static int copy_exec(bContext *C, wmOperator *op) if(sc->sel_start == sc->sel_end) return OPERATOR_CANCELLED; + console_scrollback_prompt_begin(sc, &cl_dummy); for(cl= sc->scrollback.first; cl; cl= cl->next) { offset += cl->len + 1; } - if(offset==0) + if(offset==0) { + console_scrollback_prompt_end(sc, &cl_dummy); return OPERATOR_CANCELLED; - + } offset -= 1; sel[0]= offset - sc->sel_end; @@ -750,6 +754,9 @@ static int copy_exec(bContext *C, wmOperator *op) WM_clipboard_text_set(buf_str, 0); MEM_freeN(buf_str); + + console_scrollback_prompt_end(sc, &cl_dummy); + return OPERATOR_FINISHED; } -- cgit v1.2.3 From e88b8dac7b7bba016fca80d4d2e83850ed924968 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 4 Oct 2010 15:31:04 +0000 Subject: [#22825] Copy Scenes with Audio Strip Crash. --- source/blender/blenkernel/BKE_sequencer.h | 4 ++-- source/blender/blenkernel/intern/scene.c | 7 ++++--- source/blender/blenkernel/intern/sequencer.c | 19 ++++++++++--------- .../blender/editors/space_sequencer/sequencer_edit.c | 10 +++++----- 4 files changed, 21 insertions(+), 19 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index 0766012b4a5..252c9fee8f7 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -220,14 +220,14 @@ int shuffle_seq(struct ListBase * seqbasep, struct Sequence *test, struct Scene int shuffle_seq_time(ListBase * seqbasep, struct Scene *evil_scene); int seqbase_isolated_sel_check(struct ListBase *seqbase); void free_imbuf_seq(struct Scene *scene, struct ListBase * seqbasep, int check_mem_usage, int keep_file_handles); -struct Sequence *seq_dupli_recursive(struct Scene *scene, struct Sequence * seq, int dupe_flag); +struct Sequence *seq_dupli_recursive(struct Scene *scene, struct Scene *scene_to, struct Sequence * seq, int dupe_flag); int seq_swap(struct Sequence *seq_a, struct Sequence *seq_b); void seq_update_sound(struct Scene* scene, struct Sequence *seq); void seq_update_muting(struct Scene* scene, struct Editing *ed); void seqbase_sound_reload(struct Scene *scene, ListBase *seqbase); void seqbase_unique_name_recursive(ListBase *seqbasep, struct Sequence *seq); -void seqbase_dupli_recursive(struct Scene *scene, ListBase *nseqbase, ListBase *seqbase, int dupe_flag); +void seqbase_dupli_recursive(struct Scene *scene, struct Scene *scene_to, ListBase *nseqbase, ListBase *seqbase, int dupe_flag); void clear_scene_in_allseqs(struct Main *bmain, struct Scene *sce); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 8793c412d7d..3f41b704f97 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -210,6 +210,9 @@ Scene *copy_scene(Main *bmain, Scene *sce, int type) if(type == SCE_COPY_LINK_DATA || type == SCE_COPY_FULL) { ID_NEW(scen->camera); } + + /* before scene copy */ + sound_create_scene(scen); /* world */ if(type == SCE_COPY_FULL) { @@ -221,12 +224,10 @@ Scene *copy_scene(Main *bmain, Scene *sce, int type) if(sce->ed) { scen->ed= MEM_callocN( sizeof(Editing), "addseq"); scen->ed->seqbasep= &scen->ed->seqbase; - seqbase_dupli_recursive(sce, &scen->ed->seqbase, &sce->ed->seqbase, SEQ_DUPE_ALL); + seqbase_dupli_recursive(sce, scen, &scen->ed->seqbase, &sce->ed->seqbase, SEQ_DUPE_ALL); } } - sound_create_scene(scen); - return scen; } diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index b6bb5c3a51b..430d6f87619 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -3531,8 +3531,9 @@ Sequence *sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo } -static Sequence *seq_dupli(struct Scene *scene, Sequence *seq, int dupe_flag) +static Sequence *seq_dupli(struct Scene *scene, struct Scene *scene_to, Sequence *seq, int dupe_flag) { + Scene *sce_audio= scene_to ? scene_to : scene; Sequence *seqn = MEM_dupallocN(seq); seq->tmp = seqn; @@ -3566,7 +3567,7 @@ static Sequence *seq_dupli(struct Scene *scene, Sequence *seq, int dupe_flag) } else if(seq->type == SEQ_SCENE) { seqn->strip->stripdata = 0; if(seq->scene_sound) - seqn->scene_sound = sound_scene_add_scene_sound(scene, seqn, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); + seqn->scene_sound = sound_scene_add_scene_sound(sce_audio, seqn, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); } else if(seq->type == SEQ_MOVIE) { seqn->strip->stripdata = MEM_dupallocN(seq->strip->stripdata); @@ -3575,7 +3576,7 @@ static Sequence *seq_dupli(struct Scene *scene, Sequence *seq, int dupe_flag) seqn->strip->stripdata = MEM_dupallocN(seq->strip->stripdata); if(seq->scene_sound) - seqn->scene_sound = sound_add_scene_sound(scene, seqn, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); + seqn->scene_sound = sound_add_scene_sound(sce_audio, seqn, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); seqn->sound->id.us++; } else if(seq->type == SEQ_IMAGE) { @@ -3610,13 +3611,13 @@ static Sequence *seq_dupli(struct Scene *scene, Sequence *seq, int dupe_flag) return seqn; } -Sequence * seq_dupli_recursive(struct Scene *scene, Sequence * seq, int dupe_flag) +Sequence * seq_dupli_recursive(struct Scene *scene, struct Scene *scene_to, Sequence * seq, int dupe_flag) { - Sequence * seqn = seq_dupli(scene, seq, dupe_flag); + Sequence * seqn = seq_dupli(scene, scene_to, seq, dupe_flag); if (seq->type == SEQ_META) { Sequence *s; for(s= seq->seqbase.first; s; s = s->next) { - Sequence *n = seq_dupli_recursive(scene, s, dupe_flag); + Sequence *n = seq_dupli_recursive(scene, scene_to, s, dupe_flag); if (n) { BLI_addtail(&seqn->seqbase, n); } @@ -3625,7 +3626,7 @@ Sequence * seq_dupli_recursive(struct Scene *scene, Sequence * seq, int dupe_fla return seqn; } -void seqbase_dupli_recursive(Scene *scene, ListBase *nseqbase, ListBase *seqbase, int dupe_flag) +void seqbase_dupli_recursive(Scene *scene, Scene *scene_to, ListBase *nseqbase, ListBase *seqbase, int dupe_flag) { Sequence *seq; Sequence *seqn = 0; @@ -3634,7 +3635,7 @@ void seqbase_dupli_recursive(Scene *scene, ListBase *nseqbase, ListBase *seqbase for(seq= seqbase->first; seq; seq= seq->next) { seq->tmp= NULL; if((seq->flag & SELECT) || (dupe_flag & SEQ_DUPE_ALL)) { - seqn = seq_dupli(scene, seq, dupe_flag); + seqn = seq_dupli(scene, scene_to, seq, dupe_flag); if (seqn) { /*should never fail */ if(dupe_flag & SEQ_DUPE_CONTEXT) { seq->flag &= ~SEQ_ALLSEL; @@ -3643,7 +3644,7 @@ void seqbase_dupli_recursive(Scene *scene, ListBase *nseqbase, ListBase *seqbase BLI_addtail(nseqbase, seqn); if(seq->type==SEQ_META) - seqbase_dupli_recursive(scene, &seqn->seqbase, &seq->seqbase, dupe_flag); + seqbase_dupli_recursive(scene, scene_to, &seqn->seqbase, &seq->seqbase, dupe_flag); if(dupe_flag & SEQ_DUPE_CONTEXT) { if (seq == last_seq) { diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index d1654dc5d37..84ced036f75 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -788,7 +788,7 @@ static Sequence *cut_seq_hard(Main *bmain, Scene *scene, Sequence * seq, int cut if (!skip_dup) { /* Duplicate AFTER the first change */ - seqn = seq_dupli_recursive(scene, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM); + seqn = seq_dupli_recursive(scene, NULL, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM); } if (seqn) { @@ -879,7 +879,7 @@ static Sequence *cut_seq_soft(Main *bmain, Scene *scene, Sequence * seq, int cut if (!skip_dup) { /* Duplicate AFTER the first change */ - seqn = seq_dupli_recursive(scene, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM); + seqn = seq_dupli_recursive(scene, NULL, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM); } if (seqn) { @@ -1619,7 +1619,7 @@ static int sequencer_add_duplicate_exec(bContext *C, wmOperator *op) if(ed==NULL) return OPERATOR_CANCELLED; - seqbase_dupli_recursive(scene, &nseqbase, ed->seqbasep, SEQ_DUPE_CONTEXT); + seqbase_dupli_recursive(scene, NULL, &nseqbase, ed->seqbasep, SEQ_DUPE_CONTEXT); if(nseqbase.first) { Sequence * seq= nseqbase.first; @@ -2595,7 +2595,7 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - seqbase_dupli_recursive(scene, &seqbase_clipboard, ed->seqbasep, SEQ_DUPE_UNIQUE_NAME); + seqbase_dupli_recursive(scene, NULL, &seqbase_clipboard, ed->seqbasep, SEQ_DUPE_UNIQUE_NAME); seqbase_clipboard_frame= scene->r.cfra; /* Need to remove anything that references the current scene */ @@ -2649,7 +2649,7 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op) deselect_all_seq(scene); ofs = scene->r.cfra - seqbase_clipboard_frame; - seqbase_dupli_recursive(scene, &nseqbase, &seqbase_clipboard, SEQ_DUPE_UNIQUE_NAME); + seqbase_dupli_recursive(scene, NULL, &nseqbase, &seqbase_clipboard, SEQ_DUPE_UNIQUE_NAME); /* transform pasted strips before adding */ if(ofs) { -- cgit v1.2.3 From f994c6caee126f00f97e7da9fde79bdefadd27ec Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 4 Oct 2010 19:01:25 +0000 Subject: bugfix [#24133] r32303, Mirror Modifier + EditMode + VBO's Problem. drawing the triangle arrays were only broken up by hidden faces, but switches in material were ignored. now check for materual context changes. --- source/blender/blenkernel/intern/cdderivedmesh.c | 67 +++++++++++++++--------- 1 file changed, 42 insertions(+), 25 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index ca81e216006..e2ecf21bd62 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -872,34 +872,51 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us if( !GPU_buffer_legacy(dm) ) { int tottri = dm->drawObject->nelements/3; glShadeModel(GL_SMOOTH); - - for( i = 0; i < tottri; i++ ) { - int actualFace = dm->drawObject->faceRemap[i]; - int drawSmooth = (mf[actualFace].flag & ME_SMOOTH); - int draw = 1; - - if(index) { - orig = index[actualFace]; - if(setDrawOptions && orig == ORIGINDEX_NONE) + + if(tottri == 0) { + /* avoid buffer problems in following code */ + } + if(setDrawOptions == NULL) { + /* just draw the entire face array */ + glDrawArrays(GL_TRIANGLES, 0, (tottri-1) * 3); + } + else { + /* we need to check if the next material changes */ + int next_actualFace= dm->drawObject->faceRemap[0]; + + for( i = 0; i < tottri; i++ ) { + //int actualFace = dm->drawObject->faceRemap[i]; + int actualFace = next_actualFace; + int drawSmooth = (mf[actualFace].flag & ME_SMOOTH); + int draw = 1; + + if(i != tottri-1) + next_actualFace= dm->drawObject->faceRemap[i+1]; + + if(index) { + orig = index[actualFace]; + if(orig == ORIGINDEX_NONE) + draw = 0; + } + else + orig = actualFace; + + if(draw && !setDrawOptions(userData, orig, &drawSmooth)) draw = 0; - } - else - orig = actualFace; - - if(draw && setDrawOptions && !setDrawOptions(userData, orig, &drawSmooth)) - draw = 0; - - /* Goal is to draw as long of a contiguous triangle - array as possible, so draw when we hit either an - invisible triangle or at the end of the array */ - if(!draw || i == tottri - 1) { - if(prevstart != i) - /* Add one to the length (via `draw') - if we're drawing at the end of the array */ - glDrawArrays(GL_TRIANGLES,prevstart*3, (i-prevstart+draw)*3); - prevstart = i + 1; + + /* Goal is to draw as long of a contiguous triangle + array as possible, so draw when we hit either an + invisible triangle or at the end of the array */ + if(!draw || i == tottri - 1 || mf[actualFace].mat_nr != mf[next_actualFace].mat_nr) { + if(prevstart != i) + /* Add one to the length (via `draw') + if we're drawing at the end of the array */ + glDrawArrays(GL_TRIANGLES,prevstart*3, (i-prevstart+draw)*3); + prevstart = i + 1; + } } } + glShadeModel(GL_FLAT); } GPU_buffer_unbind(); -- cgit v1.2.3 From 82209cdc86f5f248102df89b3dfeca86149768f7 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Tue, 5 Oct 2010 00:05:14 +0000 Subject: Reorganisation of COLLADA import code. Classes have been split into their own files. No functional changes. Where necessary extern "C" {} blocks have been added. --- source/blender/blenkernel/BKE_context.h | 6 +- source/blender/blenkernel/BKE_depsgraph.h | 8 + source/blender/blenkernel/BKE_fcurve.h | 8 + source/blender/blenkernel/BKE_library.h | 8 + source/blender/blenkernel/BKE_main.h | 8 + source/blender/blenkernel/BKE_scene.h | 8 + source/blender/blenkernel/BKE_texture.h | 8 + source/blender/collada/AnimationImporter.cpp | 1149 +++++++++ source/blender/collada/AnimationImporter.h | 132 + source/blender/collada/ArmatureImporter.cpp | 585 +++++ source/blender/collada/ArmatureImporter.h | 160 ++ source/blender/collada/DocumentExporter.cpp | 30 +- source/blender/collada/DocumentExporter.h | 6 + source/blender/collada/DocumentImporter.cpp | 3181 +----------------------- source/blender/collada/DocumentImporter.h | 5 + source/blender/collada/MeshImporter.cpp | 907 +++++++ source/blender/collada/MeshImporter.h | 150 ++ source/blender/collada/SkinInfo.cpp | 320 +++ source/blender/collada/SkinInfo.h | 133 + source/blender/collada/TransformReader.cpp | 125 + source/blender/collada/TransformReader.h | 70 + source/blender/collada/collada.cpp | 6 +- source/blender/collada/collada_internal.h | 11 +- source/blender/collada/collada_utils.cpp | 106 + source/blender/collada/collada_utils.h | 50 + source/blender/editors/include/ED_armature.h | 8 + source/blender/editors/include/ED_keyframing.h | 8 + source/blender/editors/include/ED_mesh.h | 8 + source/blender/editors/include/ED_object.h | 8 + source/blender/makesdna/DNA_customdata_types.h | 8 + source/blender/makesdna/DNA_texture_types.h | 8 + source/blender/makesdna/DNA_userdef_types.h | 8 + source/blender/makesrna/intern/rna_screen.c | 4 +- source/blender/windowmanager/WM_api.h | 8 + source/blender/windowmanager/WM_types.h | 8 + 35 files changed, 4058 insertions(+), 3198 deletions(-) create mode 100644 source/blender/collada/AnimationImporter.cpp create mode 100644 source/blender/collada/AnimationImporter.h create mode 100644 source/blender/collada/ArmatureImporter.cpp create mode 100644 source/blender/collada/ArmatureImporter.h create mode 100644 source/blender/collada/MeshImporter.cpp create mode 100644 source/blender/collada/MeshImporter.h create mode 100644 source/blender/collada/SkinInfo.cpp create mode 100644 source/blender/collada/SkinInfo.h create mode 100644 source/blender/collada/TransformReader.cpp create mode 100644 source/blender/collada/TransformReader.h create mode 100644 source/blender/collada/collada_utils.cpp create mode 100644 source/blender/collada/collada_utils.h (limited to 'source/blender') diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h index 9f38c5833a2..7cbaf6bdad2 100644 --- a/source/blender/blenkernel/BKE_context.h +++ b/source/blender/blenkernel/BKE_context.h @@ -28,13 +28,13 @@ #ifndef BKE_CONTEXT_H #define BKE_CONTEXT_H +#include "DNA_listBase.h" +#include "RNA_types.h" + #ifdef __cplusplus extern "C" { #endif -#include "DNA_listBase.h" -#include "RNA_types.h" - struct ARegion; struct bScreen; struct EditMesh; diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h index 0b78a1206fe..5b2dca5299c 100644 --- a/source/blender/blenkernel/BKE_depsgraph.h +++ b/source/blender/blenkernel/BKE_depsgraph.h @@ -28,6 +28,10 @@ #ifndef DEPSGRAPH_API #define DEPSGRAPH_API +#ifdef __cplusplus +extern "C" { +#endif + /* #define DEPS_DEBUG */ @@ -120,5 +124,9 @@ void DAG_pose_sort(struct Object *ob); /* callback for editors module to do updates */ void DAG_editors_update_cb(void (*func)(struct Main *bmain, struct ID *id)); + +#ifdef __cplusplus +} +#endif #endif diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h index 95e0cfc3a91..8dbfb4f2c73 100644 --- a/source/blender/blenkernel/BKE_fcurve.h +++ b/source/blender/blenkernel/BKE_fcurve.h @@ -28,6 +28,10 @@ #ifndef BKE_FCURVE_H #define BKE_FCURVE_H +#ifdef __cplusplus +extern "C" { +#endif + struct FCurve; struct FModifier; struct ChannelDriver; @@ -248,4 +252,8 @@ float fcurve_samplingcb_evalcurve(struct FCurve *fcu, void *data, float evaltime */ void fcurve_store_samples(struct FCurve *fcu, void *data, int start, int end, FcuSampleFunc sample_cb); +#ifdef __cplusplus +} +#endif + #endif /* BKE_FCURVE_H*/ diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h index e25c379ded1..b74de66f7b6 100644 --- a/source/blender/blenkernel/BKE_library.h +++ b/source/blender/blenkernel/BKE_library.h @@ -33,6 +33,10 @@ #ifndef BKE_LIBRARY_TYPES_H #define BKE_LIBRARY_TYPES_H +#ifdef __cplusplus +extern "C" { +#endif + struct ListBase; struct ID; struct Main; @@ -85,4 +89,8 @@ void set_free_windowmanager_cb(void (*func)(struct bContext *, struct wmWindowMa /* use when "" is given to new_id() */ #define ID_FALLBACK_NAME "Untitled" +#ifdef __cplusplus +} +#endif + #endif diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h index 60c2d51571f..1a53f488841 100644 --- a/source/blender/blenkernel/BKE_main.h +++ b/source/blender/blenkernel/BKE_main.h @@ -40,6 +40,10 @@ #include "DNA_listBase.h" +#ifdef __cplusplus +extern "C" { +#endif + struct Library; typedef struct Main { @@ -80,5 +84,9 @@ typedef struct Main { } Main; +#ifdef __cplusplus +} +#endif + #endif diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 96ef8d44cf4..8d5ebb64cf0 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -31,6 +31,10 @@ #ifndef BKE_SCENE_H #define BKE_SCENE_H +#ifdef __cplusplus +extern "C" { +#endif + struct AviCodecData; struct Base; struct bglMats; @@ -93,5 +97,9 @@ int get_render_child_particle_number(struct RenderData *r, int num); int get_render_shadow_samples(struct RenderData *r, int samples); float get_render_aosss_error(struct RenderData *r, float error); +#ifdef __cplusplus +} +#endif + #endif diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h index 99bb8db44ed..cbae90f4c38 100644 --- a/source/blender/blenkernel/BKE_texture.h +++ b/source/blender/blenkernel/BKE_texture.h @@ -31,6 +31,10 @@ #ifndef BKE_TEXTURE_H #define BKE_TEXTURE_H +#ifdef __cplusplus +extern "C" { +#endif + struct bNode; struct Brush; struct ColorBand; @@ -112,5 +116,9 @@ struct VoxelData *BKE_copy_voxeldata(struct VoxelData *vd); int BKE_texture_dependsOnTime(const struct Tex *texture); +#ifdef __cplusplus +} +#endif + #endif diff --git a/source/blender/collada/AnimationImporter.cpp b/source/blender/collada/AnimationImporter.cpp new file mode 100644 index 00000000000..92e863db023 --- /dev/null +++ b/source/blender/collada/AnimationImporter.cpp @@ -0,0 +1,1149 @@ +/** + * $Id: DocumentImporter.cpp 32235 2010-10-01 19:46:42Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "DNA_armature_types.h" + +#include "ED_keyframing.h" + +#include "BLI_listbase.h" +#include "BLI_math.h" +#include "BLI_path_util.h" +#include "BLI_string.h" + +#include "BKE_action.h" +#include "BKE_armature.h" +#include "BKE_fcurve.h" +#include "BKE_object.h" + +#include "MEM_guardedalloc.h" + +#include "collada_utils.h" +#include "AnimationImporter.h" +#include "ArmatureImporter.h" + +#include + +// use this for retrieving bone names, since these must be unique +template +static const char *bc_get_joint_name(T *node) +{ + const std::string& id = node->getOriginalId(); + return id.size() ? id.c_str() : node->getName().c_str(); +} + +FCurve *AnimationImporter::create_fcurve(int array_index, const char *rna_path) +{ + FCurve *fcu = (FCurve*)MEM_callocN(sizeof(FCurve), "FCurve"); + + fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED); + fcu->rna_path = BLI_strdupn(rna_path, strlen(rna_path)); + fcu->array_index = array_index; + return fcu; +} + +void AnimationImporter::create_bezt(FCurve *fcu, float frame, float output) +{ + BezTriple bez; + memset(&bez, 0, sizeof(BezTriple)); + bez.vec[1][0] = frame; + bez.vec[1][1] = output; + bez.ipo = U.ipo_new; /* use default interpolation mode here... */ + bez.f1 = bez.f2 = bez.f3 = SELECT; + bez.h1 = bez.h2 = HD_AUTO; + insert_bezt_fcurve(fcu, &bez, 0); + calchandles_fcurve(fcu); +} + +// create one or several fcurves depending on the number of parameters being animated +void AnimationImporter::animation_to_fcurves(COLLADAFW::AnimationCurve *curve) +{ + COLLADAFW::FloatOrDoubleArray& input = curve->getInputValues(); + COLLADAFW::FloatOrDoubleArray& output = curve->getOutputValues(); + // COLLADAFW::FloatOrDoubleArray& intan = curve->getInTangentValues(); + // COLLADAFW::FloatOrDoubleArray& outtan = curve->getOutTangentValues(); + float fps = (float)FPS; + size_t dim = curve->getOutDimension(); + unsigned int i; + + std::vector& fcurves = curve_map[curve->getUniqueId()]; + + switch (dim) { + case 1: // X, Y, Z or angle + case 3: // XYZ + case 16: // matrix + { + for (i = 0; i < dim; i++ ) { + FCurve *fcu = (FCurve*)MEM_callocN(sizeof(FCurve), "FCurve"); + + fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED); + // fcu->rna_path = BLI_strdupn(path, strlen(path)); + fcu->array_index = 0; + //fcu->totvert = curve->getKeyCount(); + + // create beztriple for each key + for (unsigned int j = 0; j < curve->getKeyCount(); j++) { + BezTriple bez; + memset(&bez, 0, sizeof(BezTriple)); + + // intangent + // bez.vec[0][0] = get_float_value(intan, j * 6 + i + i) * fps; + // bez.vec[0][1] = get_float_value(intan, j * 6 + i + i + 1); + + // input, output + bez.vec[1][0] = bc_get_float_value(input, j) * fps; + bez.vec[1][1] = bc_get_float_value(output, j * dim + i); + + // outtangent + // bez.vec[2][0] = get_float_value(outtan, j * 6 + i + i) * fps; + // bez.vec[2][1] = get_float_value(outtan, j * 6 + i + i + 1); + + bez.ipo = U.ipo_new; /* use default interpolation mode here... */ + bez.f1 = bez.f2 = bez.f3 = SELECT; + bez.h1 = bez.h2 = HD_AUTO; + insert_bezt_fcurve(fcu, &bez, 0); + } + + calchandles_fcurve(fcu); + + fcurves.push_back(fcu); + } + } + break; + default: + fprintf(stderr, "Output dimension of %d is not yet supported (animation id = %s)\n", dim, curve->getOriginalId().c_str()); + } + + for (std::vector::iterator it = fcurves.begin(); it != fcurves.end(); it++) + unused_curves.push_back(*it); +} + +void AnimationImporter::fcurve_deg_to_rad(FCurve *cu) +{ + for (unsigned int i = 0; i < cu->totvert; i++) { + // TODO convert handles too + cu->bezt[i].vec[1][1] *= M_PI / 180.0f; + } +} + +void AnimationImporter::add_fcurves_to_object(Object *ob, std::vector& curves, char *rna_path, int array_index, Animation *animated) +{ + bAction *act; + + if (!ob->adt || !ob->adt->action) act = verify_adt_action((ID*)&ob->id, 1); + else act = ob->adt->action; + + std::vector::iterator it; + int i; + +#if 0 + char *p = strstr(rna_path, "rotation_euler"); + bool is_rotation = p && *(p + strlen("rotation_euler")) == '\0'; + + // convert degrees to radians for rotation + if (is_rotation) + fcurve_deg_to_rad(fcu); +#endif + + for (it = curves.begin(), i = 0; it != curves.end(); it++, i++) { + FCurve *fcu = *it; + fcu->rna_path = BLI_strdupn(rna_path, strlen(rna_path)); + + if (array_index == -1) fcu->array_index = i; + else fcu->array_index = array_index; + + if (ob->type == OB_ARMATURE) { + bActionGroup *grp = NULL; + const char *bone_name = bc_get_joint_name(animated->node); + + if (bone_name) { + /* try to find group */ + grp = action_groups_find_named(act, bone_name); + + /* no matching groups, so add one */ + if (grp == NULL) { + /* Add a new group, and make it active */ + grp = (bActionGroup*)MEM_callocN(sizeof(bActionGroup), "bActionGroup"); + + grp->flag = AGRP_SELECTED; + BLI_strncpy(grp->name, bone_name, sizeof(grp->name)); + + BLI_addtail(&act->groups, grp); + BLI_uniquename(&act->groups, grp, "Group", '.', offsetof(bActionGroup, name), 64); + } + + /* add F-Curve to group */ + action_groups_add_channel(act, grp, fcu); + + } +#if 0 + if (is_rotation) { + fcurves_actionGroup_map[grp].push_back(fcu); + } +#endif + } + else { + BLI_addtail(&act->curves, fcu); + } + + // curve is used, so remove it from unused_curves + unused_curves.erase(std::remove(unused_curves.begin(), unused_curves.end(), fcu), unused_curves.end()); + } +} + +AnimationImporter::AnimationImporter(UnitConverter *conv, ArmatureImporter *arm, Scene *scene) : + TransformReader(conv), armature_importer(arm), scene(scene) { } + +AnimationImporter::~AnimationImporter() +{ + // free unused FCurves + for (std::vector::iterator it = unused_curves.begin(); it != unused_curves.end(); it++) + free_fcurve(*it); + + if (unused_curves.size()) + fprintf(stderr, "removed %u unused curves\n", unused_curves.size()); +} + +bool AnimationImporter::write_animation(const COLLADAFW::Animation* anim) +{ + if (anim->getAnimationType() == COLLADAFW::Animation::ANIMATION_CURVE) { + COLLADAFW::AnimationCurve *curve = (COLLADAFW::AnimationCurve*)anim; + + // XXX Don't know if it's necessary + // Should we check outPhysicalDimension? + if (curve->getInPhysicalDimension() != COLLADAFW::PHYSICAL_DIMENSION_TIME) { + fprintf(stderr, "Inputs physical dimension is not time. \n"); + return true; + } + + // a curve can have mixed interpolation type, + // in this case curve->getInterpolationTypes returns a list of interpolation types per key + COLLADAFW::AnimationCurve::InterpolationType interp = curve->getInterpolationType(); + + if (interp != COLLADAFW::AnimationCurve::INTERPOLATION_MIXED) { + switch (interp) { + case COLLADAFW::AnimationCurve::INTERPOLATION_LINEAR: + case COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER: + animation_to_fcurves(curve); + break; + default: + // TODO there're also CARDINAL, HERMITE, BSPLINE and STEP types + fprintf(stderr, "CARDINAL, HERMITE, BSPLINE and STEP anim interpolation types not supported yet.\n"); + break; + } + } + else { + // not supported yet + fprintf(stderr, "MIXED anim interpolation type is not supported yet.\n"); + } + } + else { + fprintf(stderr, "FORMULA animation type is not supported yet.\n"); + } + + return true; +} + +// called on post-process stage after writeVisualScenes +bool AnimationImporter::write_animation_list(const COLLADAFW::AnimationList* animlist) +{ + const COLLADAFW::UniqueId& animlist_id = animlist->getUniqueId(); + + animlist_map[animlist_id] = animlist; + +#if 0 + // should not happen + if (uid_animated_map.find(animlist_id) == uid_animated_map.end()) { + return true; + } + + // for bones rna_path is like: pose.bones["bone-name"].rotation + + // what does this AnimationList animate? + Animation& animated = uid_animated_map[animlist_id]; + Object *ob = animated.ob; + + char rna_path[100]; + char joint_path[100]; + bool is_joint = false; + + // if ob is NULL, it should be a JOINT + if (!ob) { + ob = armature_importer->get_armature_for_joint(animated.node); + + if (!ob) { + fprintf(stderr, "Cannot find armature for node %s\n", get_joint_name(animated.node)); + return true; + } + + armature_importer->get_rna_path_for_joint(animated.node, joint_path, sizeof(joint_path)); + + is_joint = true; + } + + const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings(); + + switch (animated.tm->getTransformationType()) { + case COLLADAFW::Transformation::TRANSLATE: + case COLLADAFW::Transformation::SCALE: + { + bool loc = animated.tm->getTransformationType() == COLLADAFW::Transformation::TRANSLATE; + if (is_joint) + BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, loc ? "location" : "scale"); + else + BLI_strncpy(rna_path, loc ? "location" : "scale", sizeof(rna_path)); + + for (int i = 0; i < bindings.getCount(); i++) { + const COLLADAFW::AnimationList::AnimationBinding& binding = bindings[i]; + COLLADAFW::UniqueId anim_uid = binding.animation; + + if (curve_map.find(anim_uid) == curve_map.end()) { + fprintf(stderr, "Cannot find FCurve by animation UID.\n"); + continue; + } + + std::vector& fcurves = curve_map[anim_uid]; + + switch (binding.animationClass) { + case COLLADAFW::AnimationList::POSITION_X: + add_fcurves_to_object(ob, fcurves, rna_path, 0, &animated); + break; + case COLLADAFW::AnimationList::POSITION_Y: + add_fcurves_to_object(ob, fcurves, rna_path, 1, &animated); + break; + case COLLADAFW::AnimationList::POSITION_Z: + add_fcurves_to_object(ob, fcurves, rna_path, 2, &animated); + break; + case COLLADAFW::AnimationList::POSITION_XYZ: + add_fcurves_to_object(ob, fcurves, rna_path, -1, &animated); + break; + default: + fprintf(stderr, "AnimationClass %d is not supported for %s.\n", + binding.animationClass, loc ? "TRANSLATE" : "SCALE"); + } + } + } + break; + case COLLADAFW::Transformation::ROTATE: + { + if (is_joint) + BLI_snprintf(rna_path, sizeof(rna_path), "%s.rotation_euler", joint_path); + else + BLI_strncpy(rna_path, "rotation_euler", sizeof(rna_path)); + + COLLADAFW::Rotate* rot = (COLLADAFW::Rotate*)animated.tm; + COLLADABU::Math::Vector3& axis = rot->getRotationAxis(); + + for (int i = 0; i < bindings.getCount(); i++) { + const COLLADAFW::AnimationList::AnimationBinding& binding = bindings[i]; + COLLADAFW::UniqueId anim_uid = binding.animation; + + if (curve_map.find(anim_uid) == curve_map.end()) { + fprintf(stderr, "Cannot find FCurve by animation UID.\n"); + continue; + } + + std::vector& fcurves = curve_map[anim_uid]; + + switch (binding.animationClass) { + case COLLADAFW::AnimationList::ANGLE: + if (COLLADABU::Math::Vector3::UNIT_X == axis) { + add_fcurves_to_object(ob, fcurves, rna_path, 0, &animated); + } + else if (COLLADABU::Math::Vector3::UNIT_Y == axis) { + add_fcurves_to_object(ob, fcurves, rna_path, 1, &animated); + } + else if (COLLADABU::Math::Vector3::UNIT_Z == axis) { + add_fcurves_to_object(ob, fcurves, rna_path, 2, &animated); + } + break; + case COLLADAFW::AnimationList::AXISANGLE: + // TODO convert axis-angle to quat? or XYZ? + default: + fprintf(stderr, "AnimationClass %d is not supported for ROTATE transformation.\n", + binding.animationClass); + } + } + } + break; + case COLLADAFW::Transformation::MATRIX: + case COLLADAFW::Transformation::SKEW: + case COLLADAFW::Transformation::LOOKAT: + fprintf(stderr, "Animation of MATRIX, SKEW and LOOKAT transformations is not supported yet.\n"); + break; + } +#endif + + return true; +} + +void AnimationImporter::read_node_transform(COLLADAFW::Node *node, Object *ob) +{ + float mat[4][4]; + TransformReader::get_node_mat(mat, node, &uid_animated_map, ob); + if (ob) { + copy_m4_m4(ob->obmat, mat); + object_apply_mat4(ob, ob->obmat); + } +} + +#if 0 +virtual void AnimationImporter::change_eul_to_quat(Object *ob, bAction *act) +{ + bActionGroup *grp; + int i; + + for (grp = (bActionGroup*)act->groups.first; grp; grp = grp->next) { + + FCurve *eulcu[3] = {NULL, NULL, NULL}; + + if (fcurves_actionGroup_map.find(grp) == fcurves_actionGroup_map.end()) + continue; + + std::vector &rot_fcurves = fcurves_actionGroup_map[grp]; + + if (rot_fcurves.size() > 3) continue; + + for (i = 0; i < rot_fcurves.size(); i++) + eulcu[rot_fcurves[i]->array_index] = rot_fcurves[i]; + + char joint_path[100]; + char rna_path[100]; + + BLI_snprintf(joint_path, sizeof(joint_path), "pose.bones[\"%s\"]", grp->name); + BLI_snprintf(rna_path, sizeof(rna_path), "%s.rotation_quaternion", joint_path); + + FCurve *quatcu[4] = { + create_fcurve(0, rna_path), + create_fcurve(1, rna_path), + create_fcurve(2, rna_path), + create_fcurve(3, rna_path) + }; + + bPoseChannel *chan = get_pose_channel(ob->pose, grp->name); + + float m4[4][4], irest[3][3]; + invert_m4_m4(m4, chan->bone->arm_mat); + copy_m3_m4(irest, m4); + + for (i = 0; i < 3; i++) { + + FCurve *cu = eulcu[i]; + + if (!cu) continue; + + for (int j = 0; j < cu->totvert; j++) { + float frame = cu->bezt[j].vec[1][0]; + + float eul[3] = { + eulcu[0] ? evaluate_fcurve(eulcu[0], frame) : 0.0f, + eulcu[1] ? evaluate_fcurve(eulcu[1], frame) : 0.0f, + eulcu[2] ? evaluate_fcurve(eulcu[2], frame) : 0.0f + }; + + // make eul relative to bone rest pose + float rot[3][3], rel[3][3], quat[4]; + + /*eul_to_mat3(rot, eul); + + mul_m3_m3m3(rel, irest, rot); + + mat3_to_quat(quat, rel); + */ + + eul_to_quat(quat, eul); + + for (int k = 0; k < 4; k++) + create_bezt(quatcu[k], frame, quat[k]); + } + } + + // now replace old Euler curves + + for (i = 0; i < 3; i++) { + if (!eulcu[i]) continue; + + action_groups_remove_channel(act, eulcu[i]); + free_fcurve(eulcu[i]); + } + + chan->rotmode = ROT_MODE_QUAT; + + for (i = 0; i < 4; i++) + action_groups_add_channel(act, grp, quatcu[i]); + } + + bPoseChannel *pchan; + for (pchan = (bPoseChannel*)ob->pose->chanbase.first; pchan; pchan = pchan->next) { + pchan->rotmode = ROT_MODE_QUAT; + } +} +#endif + +// prerequisites: +// animlist_map - map animlist id -> animlist +// curve_map - map anim id -> curve(s) +Object *AnimationImporter::translate_animation(COLLADAFW::Node *node, + std::map& object_map, + std::map& root_map, + COLLADAFW::Transformation::TransformationType tm_type, + Object *par_job) +{ + bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE; + bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX; + bool is_joint = node->getType() == COLLADAFW::Node::JOINT; + + COLLADAFW::Node *root = root_map.find(node->getUniqueId()) == root_map.end() ? node : root_map[node->getUniqueId()]; + Object *ob = is_joint ? armature_importer->get_armature_for_joint(node) : object_map[node->getUniqueId()]; + const char *bone_name = is_joint ? bc_get_joint_name(node) : NULL; + + if (!ob) { + fprintf(stderr, "cannot find Object for Node with id=\"%s\"\n", node->getOriginalId().c_str()); + return NULL; + } + + // frames at which to sample + std::vector frames; + + // for each , , etc. there is a separate Transformation + const COLLADAFW::TransformationPointerArray& tms = node->getTransformations(); + + unsigned int i; + + // find frames at which to sample plus convert all rotation keys to radians + for (i = 0; i < tms.getCount(); i++) { + COLLADAFW::Transformation *tm = tms[i]; + COLLADAFW::Transformation::TransformationType type = tm->getTransformationType(); + + if (type == tm_type) { + const COLLADAFW::UniqueId& listid = tm->getAnimationList(); + + if (animlist_map.find(listid) != animlist_map.end()) { + const COLLADAFW::AnimationList *animlist = animlist_map[listid]; + const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings(); + + if (bindings.getCount()) { + for (unsigned int j = 0; j < bindings.getCount(); j++) { + std::vector& curves = curve_map[bindings[j].animation]; + bool xyz = ((type == COLLADAFW::Transformation::TRANSLATE || type == COLLADAFW::Transformation::SCALE) && bindings[j].animationClass == COLLADAFW::AnimationList::POSITION_XYZ); + + if ((!xyz && curves.size() == 1) || (xyz && curves.size() == 3) || is_matrix) { + std::vector::iterator iter; + + for (iter = curves.begin(); iter != curves.end(); iter++) { + FCurve *fcu = *iter; + + if (is_rotation) + fcurve_deg_to_rad(fcu); + + for (unsigned int k = 0; k < fcu->totvert; k++) { + float fra = fcu->bezt[k].vec[1][0]; + if (std::find(frames.begin(), frames.end(), fra) == frames.end()) + frames.push_back(fra); + } + } + } + else { + fprintf(stderr, "expected %d curves, got %u\n", xyz ? 3 : 1, curves.size()); + } + } + } + } + } + } + + float irest_dae[4][4]; + float rest[4][4], irest[4][4]; + + if (is_joint) { + get_joint_rest_mat(irest_dae, root, node); + invert_m4(irest_dae); + + Bone *bone = get_named_bone((bArmature*)ob->data, bone_name); + if (!bone) { + fprintf(stderr, "cannot find bone \"%s\"\n", bone_name); + return NULL; + } + + unit_m4(rest); + copy_m4_m4(rest, bone->arm_mat); + invert_m4_m4(irest, rest); + } + + Object *job = NULL; + +#ifdef ARMATURE_TEST + FCurve *job_curves[10]; + job = get_joint_object(root, node, par_job); +#endif + + if (frames.size() == 0) + return job; + + std::sort(frames.begin(), frames.end()); + + const char *tm_str = NULL; + switch (tm_type) { + case COLLADAFW::Transformation::ROTATE: + tm_str = "rotation_quaternion"; + break; + case COLLADAFW::Transformation::SCALE: + tm_str = "scale"; + break; + case COLLADAFW::Transformation::TRANSLATE: + tm_str = "location"; + break; + case COLLADAFW::Transformation::MATRIX: + break; + default: + return job; + } + + char rna_path[200]; + char joint_path[200]; + + if (is_joint) + armature_importer->get_rna_path_for_joint(node, joint_path, sizeof(joint_path)); + + // new curves + FCurve *newcu[10]; // if tm_type is matrix, then create 10 curves: 4 rot, 3 loc, 3 scale + unsigned int totcu = is_matrix ? 10 : (is_rotation ? 4 : 3); + + for (i = 0; i < totcu; i++) { + + int axis = i; + + if (is_matrix) { + if (i < 4) { + tm_str = "rotation_quaternion"; + axis = i; + } + else if (i < 7) { + tm_str = "location"; + axis = i - 4; + } + else { + tm_str = "scale"; + axis = i - 7; + } + } + + if (is_joint) + BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, tm_str); + else + strcpy(rna_path, tm_str); + + newcu[i] = create_fcurve(axis, rna_path); + +#ifdef ARMATURE_TEST + if (is_joint) + job_curves[i] = create_fcurve(axis, tm_str); +#endif + } + + std::vector::iterator it; + + // sample values at each frame + for (it = frames.begin(); it != frames.end(); it++) { + float fra = *it; + + float mat[4][4]; + float matfra[4][4]; + + unit_m4(matfra); + + // calc object-space mat + evaluate_transform_at_frame(matfra, node, fra); + + // for joints, we need a special matrix + if (is_joint) { + // special matrix: iR * M * iR_dae * R + // where R, iR are bone rest and inverse rest mats in world space (Blender bones), + // iR_dae is joint inverse rest matrix (DAE) and M is an evaluated joint world-space matrix (DAE) + float temp[4][4], par[4][4]; + + // calc M + calc_joint_parent_mat_rest(par, NULL, root, node); + mul_m4_m4m4(temp, matfra, par); + + // evaluate_joint_world_transform_at_frame(temp, NULL, , node, fra); + + // calc special matrix + mul_serie_m4(mat, irest, temp, irest_dae, rest, NULL, NULL, NULL, NULL); + } + else { + copy_m4_m4(mat, matfra); + } + + float val[4], rot[4], loc[3], scale[3]; + + switch (tm_type) { + case COLLADAFW::Transformation::ROTATE: + mat4_to_quat(val, mat); + break; + case COLLADAFW::Transformation::SCALE: + mat4_to_size(val, mat); + break; + case COLLADAFW::Transformation::TRANSLATE: + copy_v3_v3(val, mat[3]); + break; + case COLLADAFW::Transformation::MATRIX: + mat4_to_quat(rot, mat); + copy_v3_v3(loc, mat[3]); + mat4_to_size(scale, mat); + break; + default: + break; + } + + // add keys + for (i = 0; i < totcu; i++) { + if (is_matrix) { + if (i < 4) + add_bezt(newcu[i], fra, rot[i]); + else if (i < 7) + add_bezt(newcu[i], fra, loc[i - 4]); + else + add_bezt(newcu[i], fra, scale[i - 7]); + } + else { + add_bezt(newcu[i], fra, val[i]); + } + } + +#ifdef ARMATURE_TEST + if (is_joint) { + switch (tm_type) { + case COLLADAFW::Transformation::ROTATE: + mat4_to_quat(val, matfra); + break; + case COLLADAFW::Transformation::SCALE: + mat4_to_size(val, matfra); + break; + case COLLADAFW::Transformation::TRANSLATE: + copy_v3_v3(val, matfra[3]); + break; + case MATRIX: + mat4_to_quat(rot, matfra); + copy_v3_v3(loc, matfra[3]); + mat4_to_size(scale, matfra); + break; + default: + break; + } + + for (i = 0; i < totcu; i++) { + if (is_matrix) { + if (i < 4) + add_bezt(job_curves[i], fra, rot[i]); + else if (i < 7) + add_bezt(job_curves[i], fra, loc[i - 4]); + else + add_bezt(job_curves[i], fra, scale[i - 7]); + } + else { + add_bezt(job_curves[i], fra, val[i]); + } + } + } +#endif + } + + verify_adt_action((ID*)&ob->id, 1); + + ListBase *curves = &ob->adt->action->curves; + + // add curves + for (i = 0; i < totcu; i++) { + if (is_joint) + add_bone_fcurve(ob, node, newcu[i]); + else + BLI_addtail(curves, newcu[i]); + +#ifdef ARMATURE_TEST + if (is_joint) + BLI_addtail(&job->adt->action->curves, job_curves[i]); +#endif + } + + if (is_rotation || is_matrix) { + if (is_joint) { + bPoseChannel *chan = get_pose_channel(ob->pose, bone_name); + chan->rotmode = ROT_MODE_QUAT; + } + else { + ob->rotmode = ROT_MODE_QUAT; + } + } + + return job; +} + +// internal, better make it private +// warning: evaluates only rotation +// prerequisites: animlist_map, curve_map +void AnimationImporter::evaluate_transform_at_frame(float mat[4][4], COLLADAFW::Node *node, float fra) +{ + const COLLADAFW::TransformationPointerArray& tms = node->getTransformations(); + + unit_m4(mat); + + for (unsigned int i = 0; i < tms.getCount(); i++) { + COLLADAFW::Transformation *tm = tms[i]; + COLLADAFW::Transformation::TransformationType type = tm->getTransformationType(); + float m[4][4]; + + unit_m4(m); + + if (!evaluate_animation(tm, m, fra, node->getOriginalId().c_str())) { + switch (type) { + case COLLADAFW::Transformation::ROTATE: + dae_rotate_to_mat4(tm, m); + break; + case COLLADAFW::Transformation::TRANSLATE: + dae_translate_to_mat4(tm, m); + break; + case COLLADAFW::Transformation::SCALE: + dae_scale_to_mat4(tm, m); + break; + case COLLADAFW::Transformation::MATRIX: + dae_matrix_to_mat4(tm, m); + break; + default: + fprintf(stderr, "unsupported transformation type %d\n", type); + } + } + + float temp[4][4]; + copy_m4_m4(temp, mat); + + mul_m4_m4m4(mat, m, temp); + } +} + +// return true to indicate that mat contains a sane value +bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm, float mat[4][4], float fra, const char *node_id) +{ + const COLLADAFW::UniqueId& listid = tm->getAnimationList(); + COLLADAFW::Transformation::TransformationType type = tm->getTransformationType(); + + if (type != COLLADAFW::Transformation::ROTATE && + type != COLLADAFW::Transformation::SCALE && + type != COLLADAFW::Transformation::TRANSLATE && + type != COLLADAFW::Transformation::MATRIX) { + fprintf(stderr, "animation of transformation %d is not supported yet\n", type); + return false; + } + + if (animlist_map.find(listid) == animlist_map.end()) + return false; + + const COLLADAFW::AnimationList *animlist = animlist_map[listid]; + const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings(); + + if (bindings.getCount()) { + float vec[3]; + + bool is_scale = (type == COLLADAFW::Transformation::SCALE); + bool is_translate = (type == COLLADAFW::Transformation::TRANSLATE); + + if (type == COLLADAFW::Transformation::SCALE) + dae_scale_to_v3(tm, vec); + else if (type == COLLADAFW::Transformation::TRANSLATE) + dae_translate_to_v3(tm, vec); + + for (unsigned int j = 0; j < bindings.getCount(); j++) { + const COLLADAFW::AnimationList::AnimationBinding& binding = bindings[j]; + std::vector& curves = curve_map[binding.animation]; + COLLADAFW::AnimationList::AnimationClass animclass = binding.animationClass; + char path[100]; + + switch (type) { + case COLLADAFW::Transformation::ROTATE: + BLI_snprintf(path, sizeof(path), "%s.rotate (binding %u)", node_id, j); + break; + case COLLADAFW::Transformation::SCALE: + BLI_snprintf(path, sizeof(path), "%s.scale (binding %u)", node_id, j); + break; + case COLLADAFW::Transformation::TRANSLATE: + BLI_snprintf(path, sizeof(path), "%s.translate (binding %u)", node_id, j); + break; + case COLLADAFW::Transformation::MATRIX: + BLI_snprintf(path, sizeof(path), "%s.matrix (binding %u)", node_id, j); + break; + default: + break; + } + + if (animclass == COLLADAFW::AnimationList::UNKNOWN_CLASS) { + fprintf(stderr, "%s: UNKNOWN animation class\n", path); + continue; + } + + if (type == COLLADAFW::Transformation::ROTATE) { + if (curves.size() != 1) { + fprintf(stderr, "expected 1 curve, got %u\n", curves.size()); + return false; + } + + // TODO support other animclasses + if (animclass != COLLADAFW::AnimationList::ANGLE) { + fprintf(stderr, "%s: animation class %d is not supported yet\n", path, animclass); + return false; + } + + COLLADABU::Math::Vector3& axis = ((COLLADAFW::Rotate*)tm)->getRotationAxis(); + float ax[3] = {axis[0], axis[1], axis[2]}; + float angle = evaluate_fcurve(curves[0], fra); + axis_angle_to_mat4(mat, ax, angle); + + return true; + } + else if (is_scale || is_translate) { + bool is_xyz = animclass == COLLADAFW::AnimationList::POSITION_XYZ; + + if ((!is_xyz && curves.size() != 1) || (is_xyz && curves.size() != 3)) { + if (is_xyz) + fprintf(stderr, "%s: expected 3 curves, got %u\n", path, curves.size()); + else + fprintf(stderr, "%s: expected 1 curve, got %u\n", path, curves.size()); + return false; + } + + switch (animclass) { + case COLLADAFW::AnimationList::POSITION_X: + vec[0] = evaluate_fcurve(curves[0], fra); + break; + case COLLADAFW::AnimationList::POSITION_Y: + vec[1] = evaluate_fcurve(curves[0], fra); + break; + case COLLADAFW::AnimationList::POSITION_Z: + vec[2] = evaluate_fcurve(curves[0], fra); + break; + case COLLADAFW::AnimationList::POSITION_XYZ: + vec[0] = evaluate_fcurve(curves[0], fra); + vec[1] = evaluate_fcurve(curves[1], fra); + vec[2] = evaluate_fcurve(curves[2], fra); + break; + default: + fprintf(stderr, "%s: animation class %d is not supported yet\n", path, animclass); + break; + } + } + else if (type == COLLADAFW::Transformation::MATRIX) { + // for now, of matrix animation, support only the case when all values are packed into one animation + if (curves.size() != 16) { + fprintf(stderr, "%s: expected 16 curves, got %u\n", path, curves.size()); + return false; + } + + COLLADABU::Math::Matrix4 matrix; + int i = 0, j = 0; + + for (std::vector::iterator it = curves.begin(); it != curves.end(); it++) { + matrix.setElement(i, j, evaluate_fcurve(*it, fra)); + j++; + if (j == 4) { + i++; + j = 0; + } + } + + COLLADAFW::Matrix tm(matrix); + dae_matrix_to_mat4(&tm, mat); + + return true; + } + } + + if (is_scale) + size_to_mat4(mat, vec); + else + copy_v3_v3(mat[3], vec); + + return is_scale || is_translate; + } + + return false; +} + +// gives a world-space mat of joint at rest position +void AnimationImporter::get_joint_rest_mat(float mat[4][4], COLLADAFW::Node *root, COLLADAFW::Node *node) +{ + // if bind mat is not available, + // use "current" node transform, i.e. all those tms listed inside + if (!armature_importer->get_joint_bind_mat(mat, node)) { + float par[4][4], m[4][4]; + + calc_joint_parent_mat_rest(par, NULL, root, node); + get_node_mat(m, node, NULL, NULL); + mul_m4_m4m4(mat, m, par); + } +} + +// gives a world-space mat, end's mat not included +bool AnimationImporter::calc_joint_parent_mat_rest(float mat[4][4], float par[4][4], COLLADAFW::Node *node, COLLADAFW::Node *end) +{ + float m[4][4]; + + if (node == end) { + par ? copy_m4_m4(mat, par) : unit_m4(mat); + return true; + } + + // use bind matrix if available or calc "current" world mat + if (!armature_importer->get_joint_bind_mat(m, node)) { + if (par) { + float temp[4][4]; + get_node_mat(temp, node, NULL, NULL); + mul_m4_m4m4(m, temp, par); + } + else { + get_node_mat(m, node, NULL, NULL); + } + } + + COLLADAFW::NodePointerArray& children = node->getChildNodes(); + for (unsigned int i = 0; i < children.getCount(); i++) { + if (calc_joint_parent_mat_rest(mat, m, children[i], end)) + return true; + } + + return false; +} + +#ifdef ARMATURE_TEST +Object *AnimationImporter::get_joint_object(COLLADAFW::Node *root, COLLADAFW::Node *node, Object *par_job) +{ + if (joint_objects.find(node->getUniqueId()) == joint_objects.end()) { + Object *job = add_object(scene, OB_EMPTY); + + rename_id((ID*)&job->id, (char*)get_joint_name(node)); + + job->lay = object_in_scene(job, scene)->lay = 2; + + mul_v3_fl(job->size, 0.5f); + job->recalc |= OB_RECALC_OB; + + verify_adt_action((ID*)&job->id, 1); + + job->rotmode = ROT_MODE_QUAT; + + float mat[4][4]; + get_joint_rest_mat(mat, root, node); + + if (par_job) { + float temp[4][4], ipar[4][4]; + invert_m4_m4(ipar, par_job->obmat); + copy_m4_m4(temp, mat); + mul_m4_m4m4(mat, temp, ipar); + } + + TransformBase::decompose(mat, job->loc, NULL, job->quat, job->size); + + if (par_job) { + job->parent = par_job; + + par_job->recalc |= OB_RECALC_OB; + job->parsubstr[0] = 0; + } + + where_is_object(scene, job); + + // after parenting and layer change + DAG_scene_sort(CTX_data_main(C), scene); + + joint_objects[node->getUniqueId()] = job; + } + + return joint_objects[node->getUniqueId()]; +} +#endif + +#if 0 +// recursively evaluates joint tree until end is found, mat then is world-space matrix of end +// mat must be identity on enter, node must be root +bool AnimationImporter::evaluate_joint_world_transform_at_frame(float mat[4][4], float par[4][4], COLLADAFW::Node *node, COLLADAFW::Node *end, float fra) +{ + float m[4][4]; + if (par) { + float temp[4][4]; + evaluate_transform_at_frame(temp, node, node == end ? fra : 0.0f); + mul_m4_m4m4(m, temp, par); + } + else { + evaluate_transform_at_frame(m, node, node == end ? fra : 0.0f); + } + + if (node == end) { + copy_m4_m4(mat, m); + return true; + } + else { + COLLADAFW::NodePointerArray& children = node->getChildNodes(); + for (int i = 0; i < children.getCount(); i++) { + if (evaluate_joint_world_transform_at_frame(mat, m, children[i], end, fra)) + return true; + } + } + + return false; +} +#endif + +void AnimationImporter::add_bone_fcurve(Object *ob, COLLADAFW::Node *node, FCurve *fcu) +{ + const char *bone_name = bc_get_joint_name(node); + bAction *act = ob->adt->action; + + /* try to find group */ + bActionGroup *grp = action_groups_find_named(act, bone_name); + + /* no matching groups, so add one */ + if (grp == NULL) { + /* Add a new group, and make it active */ + grp = (bActionGroup*)MEM_callocN(sizeof(bActionGroup), "bActionGroup"); + + grp->flag = AGRP_SELECTED; + BLI_strncpy(grp->name, bone_name, sizeof(grp->name)); + + BLI_addtail(&act->groups, grp); + BLI_uniquename(&act->groups, grp, "Group", '.', offsetof(bActionGroup, name), 64); + } + + /* add F-Curve to group */ + action_groups_add_channel(act, grp, fcu); +} + +void AnimationImporter::add_bezt(FCurve *fcu, float fra, float value) +{ + BezTriple bez; + memset(&bez, 0, sizeof(BezTriple)); + bez.vec[1][0] = fra; + bez.vec[1][1] = value; + bez.ipo = U.ipo_new; /* use default interpolation mode here... */ + bez.f1 = bez.f2 = bez.f3 = SELECT; + bez.h1 = bez.h2 = HD_AUTO; + insert_bezt_fcurve(fcu, &bez, 0); + calchandles_fcurve(fcu); +} diff --git a/source/blender/collada/AnimationImporter.h b/source/blender/collada/AnimationImporter.h new file mode 100644 index 00000000000..9854a9d2663 --- /dev/null +++ b/source/blender/collada/AnimationImporter.h @@ -0,0 +1,132 @@ +/** + * $Id: DocumentImporter.cpp 32235 2010-10-01 19:46:42Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BC_ANIMATIONIMPORTER_H__ +#define __BC_ANIMATIONIMPORTER_H__ + +#include +#include + +#include "COLLADAFWAnimation.h" +#include "COLLADAFWAnimationCurve.h" +#include "COLLADAFWAnimationList.h" +#include "COLLADAFWNode.h" +#include "COLLADAFWUniqueId.h" + +#include "DNA_anim_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +//#include "ArmatureImporter.h" +#include "TransformReader.h" + +#include "collada_internal.h" + +class ArmatureImporter; + +class AnimationImporterBase +{ +public: + // virtual void change_eul_to_quat(Object *ob, bAction *act) = 0; +}; + +class AnimationImporter : private TransformReader, public AnimationImporterBase +{ +private: + + ArmatureImporter *armature_importer; + Scene *scene; + + std::map > curve_map; + std::map uid_animated_map; + // std::map > fcurves_actionGroup_map; + std::map animlist_map; + std::vector unused_curves; + std::map joint_objects; + + FCurve *create_fcurve(int array_index, const char *rna_path); + + void create_bezt(FCurve *fcu, float frame, float output); + + // create one or several fcurves depending on the number of parameters being animated + void animation_to_fcurves(COLLADAFW::AnimationCurve *curve); + + void fcurve_deg_to_rad(FCurve *cu); + + void add_fcurves_to_object(Object *ob, std::vector& curves, char *rna_path, int array_index, Animation *animated); +public: + + AnimationImporter(UnitConverter *conv, ArmatureImporter *arm, Scene *scene); + + ~AnimationImporter(); + + bool write_animation(const COLLADAFW::Animation* anim); + + // called on post-process stage after writeVisualScenes + bool write_animation_list(const COLLADAFW::AnimationList* animlist); + + void read_node_transform(COLLADAFW::Node *node, Object *ob); +#if 0 + virtual void change_eul_to_quat(Object *ob, bAction *act); +#endif + + // prerequisites: + // animlist_map - map animlist id -> animlist + // curve_map - map anim id -> curve(s) + Object *translate_animation(COLLADAFW::Node *node, + std::map& object_map, + std::map& root_map, + COLLADAFW::Transformation::TransformationType tm_type, + Object *par_job = NULL); + + // internal, better make it private + // warning: evaluates only rotation + // prerequisites: animlist_map, curve_map + void evaluate_transform_at_frame(float mat[4][4], COLLADAFW::Node *node, float fra); + + // return true to indicate that mat contains a sane value + bool evaluate_animation(COLLADAFW::Transformation *tm, float mat[4][4], float fra, const char *node_id); + + // gives a world-space mat of joint at rest position + void get_joint_rest_mat(float mat[4][4], COLLADAFW::Node *root, COLLADAFW::Node *node); + + // gives a world-space mat, end's mat not included + bool calc_joint_parent_mat_rest(float mat[4][4], float par[4][4], COLLADAFW::Node *node, COLLADAFW::Node *end); + +#ifdef ARMATURE_TEST + Object *get_joint_object(COLLADAFW::Node *root, COLLADAFW::Node *node, Object *par_job); +#endif + +#if 0 + // recursively evaluates joint tree until end is found, mat then is world-space matrix of end + // mat must be identity on enter, node must be root + bool evaluate_joint_world_transform_at_frame(float mat[4][4], float par[4][4], COLLADAFW::Node *node, COLLADAFW::Node *end, float fra); +#endif + + void add_bone_fcurve(Object *ob, COLLADAFW::Node *node, FCurve *fcu); + + void add_bezt(FCurve *fcu, float fra, float value); +}; + + #endif \ No newline at end of file diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp new file mode 100644 index 00000000000..f931c04aef1 --- /dev/null +++ b/source/blender/collada/ArmatureImporter.cpp @@ -0,0 +1,585 @@ +/** + * $Id: DocumentImporter.cpp 32235 2010-10-01 19:46:42Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include + +#include "COLLADAFWUniqueId.h" + +#include "BKE_action.h" +#include "BKE_depsgraph.h" +#include "BKE_object.h" +#include "BLI_string.h" +#include "ED_armature.h" + +#include "ArmatureImporter.h" + +// use this for retrieving bone names, since these must be unique +template +static const char *bc_get_joint_name(T *node) +{ + const std::string& id = node->getOriginalId(); + return id.size() ? id.c_str() : node->getName().c_str(); +} + +ArmatureImporter::ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, AnimationImporterBase *anim, Scene *sce) : + TransformReader(conv), scene(sce), empty(NULL), mesh_importer(mesh), anim_importer(anim) {} + +ArmatureImporter::~ArmatureImporter() +{ + // free skin controller data if we forget to do this earlier + std::map::iterator it; + for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) { + it->second.free(); + } +} + +#if 0 +JointData *ArmatureImporter::get_joint_data(COLLADAFW::Node *node); +{ + const COLLADAFW::UniqueId& joint_id = node->getUniqueId(); + + if (joint_id_to_joint_index_map.find(joint_id) == joint_id_to_joint_index_map.end()) { + fprintf(stderr, "Cannot find a joint index by joint id for %s.\n", + node->getOriginalId().c_str()); + return NULL; + } + + int joint_index = joint_id_to_joint_index_map[joint_id]; + + return &joint_index_to_joint_info_map[joint_index]; +} +#endif + +void ArmatureImporter::create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBone *parent, int totchild, + float parent_mat[][4], bArmature *arm) +{ + float joint_inv_bind_mat[4][4]; + + // JointData* jd = get_joint_data(node); + + float mat[4][4]; + + if (skin.get_joint_inv_bind_matrix(joint_inv_bind_mat, node)) { + // get original world-space matrix + invert_m4_m4(mat, joint_inv_bind_mat); + } + // create a bone even if there's no joint data for it (i.e. it has no influence) + else { + float obmat[4][4]; + + // object-space + get_node_mat(obmat, node, NULL, NULL); + + // get world-space + if (parent) + mul_m4_m4m4(mat, obmat, parent_mat); + else + copy_m4_m4(mat, obmat); + } + + // TODO rename from Node "name" attrs later + EditBone *bone = ED_armature_edit_bone_add(arm, (char*)bc_get_joint_name(node)); + totbone++; + + if (parent) bone->parent = parent; + + // set head + copy_v3_v3(bone->head, mat[3]); + + // set tail, don't set it to head because 0-length bones are not allowed + float vec[3] = {0.0f, 0.5f, 0.0f}; + add_v3_v3v3(bone->tail, bone->head, vec); + + // set parent tail + if (parent && totchild == 1) { + copy_v3_v3(parent->tail, bone->head); + + // not setting BONE_CONNECTED because this would lock child bone location with respect to parent + // bone->flag |= BONE_CONNECTED; + + // XXX increase this to prevent "very" small bones? + const float epsilon = 0.000001f; + + // derive leaf bone length + float length = len_v3v3(parent->head, parent->tail); + if ((length < leaf_bone_length || totbone == 0) && length > epsilon) { + leaf_bone_length = length; + } + + // treat zero-sized bone like a leaf bone + if (length <= epsilon) { + add_leaf_bone(parent_mat, parent); + } + + /* +#if 0 + // and which row in mat is bone direction + float vec[3]; + sub_v3_v3v3(vec, parent->tail, parent->head); +#ifdef COLLADA_DEBUG + print_v3("tail - head", vec); + print_m4("matrix", parent_mat); +#endif + for (int i = 0; i < 3; i++) { +#ifdef COLLADA_DEBUG + char *axis_names[] = {"X", "Y", "Z"}; + printf("%s-axis length is %f\n", axis_names[i], len_v3(parent_mat[i])); +#endif + float angle = angle_v2v2(vec, parent_mat[i]); + if (angle < min_angle) { +#ifdef COLLADA_DEBUG + print_v3("picking", parent_mat[i]); + printf("^ %s axis of %s's matrix\n", axis_names[i], get_dae_name(node)); +#endif + bone_direction_row = i; + min_angle = angle; + } + } +#endif + */ + } + + COLLADAFW::NodePointerArray& children = node->getChildNodes(); + for (unsigned int i = 0; i < children.getCount(); i++) { + create_bone(skin, children[i], bone, children.getCount(), mat, arm); + } + + // in second case it's not a leaf bone, but we handle it the same way + if (!children.getCount() || children.getCount() > 1) { + add_leaf_bone(mat, bone); + } +} + +void ArmatureImporter::add_leaf_bone(float mat[][4], EditBone *bone) +{ + LeafBone leaf; + + leaf.bone = bone; + copy_m4_m4(leaf.mat, mat); + BLI_strncpy(leaf.name, bone->name, sizeof(leaf.name)); + + leaf_bones.push_back(leaf); +} + +void ArmatureImporter::fix_leaf_bones() +{ + // just setting tail for leaf bones here + + std::vector::iterator it; + for (it = leaf_bones.begin(); it != leaf_bones.end(); it++) { + LeafBone& leaf = *it; + + // pointing up + float vec[3] = {0.0f, 0.0f, 1.0f}; + + mul_v3_fl(vec, leaf_bone_length); + + copy_v3_v3(leaf.bone->tail, leaf.bone->head); + add_v3_v3v3(leaf.bone->tail, leaf.bone->head, vec); + } +} + +void ArmatureImporter::set_leaf_bone_shapes(Object *ob_arm) +{ + bPose *pose = ob_arm->pose; + + std::vector::iterator it; + for (it = leaf_bones.begin(); it != leaf_bones.end(); it++) { + LeafBone& leaf = *it; + + bPoseChannel *pchan = get_pose_channel(pose, leaf.name); + if (pchan) { + pchan->custom = get_empty_for_leaves(); + } + else { + fprintf(stderr, "Cannot find a pose channel for leaf bone %s\n", leaf.name); + } + } +} + +#if 0 +void ArmatureImporter::set_euler_rotmode() +{ + // just set rotmode = ROT_MODE_EUL on pose channel for each joint + + std::map::iterator it; + + for (it = joint_by_uid.begin(); it != joint_by_uid.end(); it++) { + + COLLADAFW::Node *joint = it->second; + + std::map::iterator sit; + + for (sit = skin_by_data_uid.begin(); sit != skin_by_data_uid.end(); sit++) { + SkinInfo& skin = sit->second; + + if (skin.uses_joint_or_descendant(joint)) { + bPoseChannel *pchan = skin.get_pose_channel_from_node(joint); + + if (pchan) { + pchan->rotmode = ROT_MODE_EUL; + } + else { + fprintf(stderr, "Cannot find pose channel for %s.\n", get_joint_name(joint)); + } + + break; + } + } + } +} +#endif + +Object *ArmatureImporter::get_empty_for_leaves() +{ + if (empty) return empty; + + empty = add_object(scene, OB_EMPTY); + empty->empty_drawtype = OB_EMPTY_SPHERE; + + return empty; +} + +#if 0 +Object *ArmatureImporter::find_armature(COLLADAFW::Node *node) +{ + JointData* jd = get_joint_data(node); + if (jd) return jd->ob_arm; + + COLLADAFW::NodePointerArray& children = node->getChildNodes(); + for (int i = 0; i < children.getCount(); i++) { + Object *ob_arm = find_armature(children[i]); + if (ob_arm) return ob_arm; + } + + return NULL; +} + +ArmatureJoints& ArmatureImporter::get_armature_joints(Object *ob_arm) +{ + // try finding it + std::vector::iterator it; + for (it = armature_joints.begin(); it != armature_joints.end(); it++) { + if ((*it).ob_arm == ob_arm) return *it; + } + + // not found, create one + ArmatureJoints aj; + aj.ob_arm = ob_arm; + armature_joints.push_back(aj); + + return armature_joints.back(); +} +#endif + +void ArmatureImporter::create_armature_bones(SkinInfo& skin) +{ + // just do like so: + // - get armature + // - enter editmode + // - add edit bones and head/tail properties using matrices and parent-child info + // - exit edit mode + // - set a sphere shape to leaf bones + + Object *ob_arm = NULL; + + /* + * find if there's another skin sharing at least one bone with this skin + * if so, use that skin's armature + */ + + /* + Pseudocode: + + find_node_in_tree(node, root_joint) + + skin::find_root_joints(root_joints): + std::vector root_joints; + for each root in root_joints: + for each joint in joints: + if find_node_in_tree(joint, root): + if (std::find(root_joints.begin(), root_joints.end(), root) == root_joints.end()) + root_joints.push_back(root); + + for (each skin B with armature) { + find all root joints for skin B + + for each joint X in skin A: + for each root joint R in skin B: + if (find_node_in_tree(X, R)) { + shared = 1; + goto endloop; + } + } + + endloop: + */ + + SkinInfo *a = &skin; + Object *shared = NULL; + std::vector skin_root_joints; + + std::map::iterator it; + for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) { + SkinInfo *b = &it->second; + if (b == a || b->get_armature() == NULL) + continue; + + skin_root_joints.clear(); + + b->find_root_joints(root_joints, joint_by_uid, skin_root_joints); + + std::vector::iterator ri; + for (ri = skin_root_joints.begin(); ri != skin_root_joints.end(); ri++) { + if (a->uses_joint_or_descendant(*ri)) { + shared = b->get_armature(); + break; + } + } + + if (shared != NULL) + break; + } + + if (shared) + ob_arm = skin.set_armature(shared); + else + ob_arm = skin.create_armature(scene); + + // enter armature edit mode + ED_armature_to_edit(ob_arm); + + leaf_bones.clear(); + totbone = 0; + // bone_direction_row = 1; // TODO: don't default to Y but use asset and based on it decide on default row + leaf_bone_length = 0.1f; + // min_angle = 360.0f; // minimum angle between bone head-tail and a row of bone matrix + + // create bones + /* + TODO: + check if bones have already been created for a given joint + */ + + std::vector::iterator ri; + for (ri = root_joints.begin(); ri != root_joints.end(); ri++) { + // for shared armature check if bone tree is already created + if (shared && std::find(skin_root_joints.begin(), skin_root_joints.end(), *ri) != skin_root_joints.end()) + continue; + + // since root_joints may contain joints for multiple controllers, we need to filter + if (skin.uses_joint_or_descendant(*ri)) { + create_bone(skin, *ri, NULL, (*ri)->getChildNodes().getCount(), NULL, (bArmature*)ob_arm->data); + + if (joint_parent_map.find((*ri)->getUniqueId()) != joint_parent_map.end() && !skin.get_parent()) + skin.set_parent(joint_parent_map[(*ri)->getUniqueId()]); + } + } + + fix_leaf_bones(); + + // exit armature edit mode + ED_armature_from_edit(ob_arm); + ED_armature_edit_free(ob_arm); + DAG_id_flush_update(&ob_arm->id, OB_RECALC_OB|OB_RECALC_DATA); + + set_leaf_bone_shapes(ob_arm); + + // set_euler_rotmode(); +} + + +// root - if this joint is the top joint in hierarchy, if a joint +// is a child of a node (not joint), root should be true since +// this is where we build armature bones from +void ArmatureImporter::add_joint(COLLADAFW::Node *node, bool root, Object *parent) +{ + joint_by_uid[node->getUniqueId()] = node; + if (root) { + root_joints.push_back(node); + + if (parent) + joint_parent_map[node->getUniqueId()] = parent; + } +} + +#if 0 +void ArmatureImporter::add_root_joint(COLLADAFW::Node *node) +{ + // root_joints.push_back(node); + Object *ob_arm = find_armature(node); + if (ob_arm) { + get_armature_joints(ob_arm).root_joints.push_back(node); + } +#ifdef COLLADA_DEBUG + else { + fprintf(stderr, "%s cannot be added to armature.\n", get_joint_name(node)); + } +#endif +} +#endif + +// here we add bones to armatures, having armatures previously created in write_controller +void ArmatureImporter::make_armatures(bContext *C) +{ + std::map::iterator it; + for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) { + + SkinInfo& skin = it->second; + + create_armature_bones(skin); + + // link armature with a mesh object + Object *ob = mesh_importer->get_object_by_geom_uid(*get_geometry_uid(skin.get_controller_uid())); + if (ob) + skin.link_armature(C, ob, joint_by_uid, this); + else + fprintf(stderr, "Cannot find object to link armature with.\n"); + + // set armature parent if any + Object *par = skin.get_parent(); + if (par) + bc_set_parent(skin.get_armature(), par, C, false); + + // free memory stolen from SkinControllerData + skin.free(); + } +} + +#if 0 +// link with meshes, create vertex groups, assign weights +void ArmatureImporter::link_armature(Object *ob_arm, const COLLADAFW::UniqueId& geom_id, const COLLADAFW::UniqueId& controller_data_id) +{ + Object *ob = mesh_importer->get_object_by_geom_uid(geom_id); + + if (!ob) { + fprintf(stderr, "Cannot find object by geometry UID.\n"); + return; + } + + if (skin_by_data_uid.find(controller_data_id) == skin_by_data_uid.end()) { + fprintf(stderr, "Cannot find skin info by controller data UID.\n"); + return; + } + + SkinInfo& skin = skin_by_data_uid[conroller_data_id]; + + // create vertex groups +} +#endif + +bool ArmatureImporter::write_skin_controller_data(const COLLADAFW::SkinControllerData* data) +{ + // at this stage we get vertex influence info that should go into me->verts and ob->defbase + // there's no info to which object this should be long so we associate it with skin controller data UID + + // don't forget to call defgroup_unique_name before we copy + + // controller data uid -> [armature] -> joint data, + // [mesh object] + // + + SkinInfo skin(unit_converter); + skin.borrow_skin_controller_data(data); + + // store join inv bind matrix to use it later in armature construction + const COLLADAFW::Matrix4Array& inv_bind_mats = data->getInverseBindMatrices(); + for (unsigned int i = 0; i < data->getJointsCount(); i++) { + skin.add_joint(inv_bind_mats[i]); + } + + skin_by_data_uid[data->getUniqueId()] = skin; + + return true; +} + +bool ArmatureImporter::write_controller(const COLLADAFW::Controller* controller) +{ + // - create and store armature object + + const COLLADAFW::UniqueId& skin_id = controller->getUniqueId(); + + if (controller->getControllerType() == COLLADAFW::Controller::CONTROLLER_TYPE_SKIN) { + COLLADAFW::SkinController *co = (COLLADAFW::SkinController*)controller; + // to be able to find geom id by controller id + geom_uid_by_controller_uid[skin_id] = co->getSource(); + + const COLLADAFW::UniqueId& data_uid = co->getSkinControllerData(); + if (skin_by_data_uid.find(data_uid) == skin_by_data_uid.end()) { + fprintf(stderr, "Cannot find skin by controller data UID.\n"); + return true; + } + + skin_by_data_uid[data_uid].set_controller(co); + } + // morph controller + else { + // shape keys? :) + fprintf(stderr, "Morph controller is not supported yet.\n"); + } + + return true; +} + +COLLADAFW::UniqueId *ArmatureImporter::get_geometry_uid(const COLLADAFW::UniqueId& controller_uid) +{ + if (geom_uid_by_controller_uid.find(controller_uid) == geom_uid_by_controller_uid.end()) + return NULL; + + return &geom_uid_by_controller_uid[controller_uid]; +} + +Object *ArmatureImporter::get_armature_for_joint(COLLADAFW::Node *node) +{ + std::map::iterator it; + for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) { + SkinInfo& skin = it->second; + + if (skin.uses_joint_or_descendant(node)) + return skin.get_armature(); + } + + return NULL; +} + +void ArmatureImporter::get_rna_path_for_joint(COLLADAFW::Node *node, char *joint_path, size_t count) +{ + BLI_snprintf(joint_path, count, "pose.bones[\"%s\"]", bc_get_joint_name(node)); +} + +// gives a world-space mat +bool ArmatureImporter::get_joint_bind_mat(float m[][4], COLLADAFW::Node *joint) +{ + std::map::iterator it; + bool found = false; + for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) { + SkinInfo& skin = it->second; + if ((found = skin.get_joint_inv_bind_matrix(m, joint))) { + invert_m4(m); + break; + } + } + + return found; +} \ No newline at end of file diff --git a/source/blender/collada/ArmatureImporter.h b/source/blender/collada/ArmatureImporter.h new file mode 100644 index 00000000000..64d4669b33c --- /dev/null +++ b/source/blender/collada/ArmatureImporter.h @@ -0,0 +1,160 @@ +/** + * $Id: DocumentImporter.cpp 32235 2010-10-01 19:46:42Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BC_ARMATUREIMPORTER_H__ +#define __BC_ARMATUREIMPORTER_H__ + +#include "COLLADAFWNode.h" +#include "COLLADAFWUniqueId.h" + +extern "C" { +#include "BKE_context.h" + +#include "DNA_armature_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "ED_armature.h" +} + +#include "AnimationImporter.h" +#include "MeshImporter.h" +#include "SkinInfo.h" +#include "TransformReader.h" + +#include +#include + +#include "collada_internal.h" +#include "collada_utils.h" + +class ArmatureImporter : private TransformReader +{ +private: + Scene *scene; + UnitConverter *unit_converter; + + // std::map joint_index_to_joint_info_map; + // std::map joint_id_to_joint_index_map; + + struct LeafBone { + // COLLADAFW::Node *node; + EditBone *bone; + char name[32]; + float mat[4][4]; // bone matrix, derived from inv_bind_mat + }; + std::vector leaf_bones; + // int bone_direction_row; // XXX not used + float leaf_bone_length; + int totbone; + // XXX not used + // float min_angle; // minimum angle between bone head-tail and a row of bone matrix + +#if 0 + struct ArmatureJoints { + Object *ob_arm; + std::vector root_joints; + }; + std::vector armature_joints; +#endif + + Object *empty; // empty for leaf bones + + std::map geom_uid_by_controller_uid; + std::map joint_by_uid; // contains all joints + std::vector root_joints; + std::map joint_parent_map; + + MeshImporterBase *mesh_importer; + AnimationImporterBase *anim_importer; + + // This is used to store data passed in write_controller_data. + // Arrays from COLLADAFW::SkinControllerData lose ownership, so do this class members + // so that arrays don't get freed until we free them explicitly. + + std::map skin_by_data_uid; // data UID = skin controller data UID +#if 0 + JointData *get_joint_data(COLLADAFW::Node *node); +#endif + + void create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBone *parent, int totchild, + float parent_mat[][4], bArmature *arm); + + void add_leaf_bone(float mat[][4], EditBone *bone); + + void fix_leaf_bones(); + + void set_leaf_bone_shapes(Object *ob_arm); + +#if 0 + void set_euler_rotmode(); +#endif + + Object *get_empty_for_leaves(); + +#if 0 + Object *find_armature(COLLADAFW::Node *node); + + ArmatureJoints& get_armature_joints(Object *ob_arm); +#endif + + void create_armature_bones(SkinInfo& skin); + +public: + + ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, AnimationImporterBase *anim, Scene *sce); + ~ArmatureImporter(); + + // root - if this joint is the top joint in hierarchy, if a joint + // is a child of a node (not joint), root should be true since + // this is where we build armature bones from + void add_joint(COLLADAFW::Node *node, bool root, Object *parent); + +#if 0 + void add_root_joint(COLLADAFW::Node *node); +#endif + + // here we add bones to armatures, having armatures previously created in write_controller + void make_armatures(bContext *C); + +#if 0 + // link with meshes, create vertex groups, assign weights + void link_armature(Object *ob_arm, const COLLADAFW::UniqueId& geom_id, const COLLADAFW::UniqueId& controller_data_id); +#endif + + bool write_skin_controller_data(const COLLADAFW::SkinControllerData* data); + + bool write_controller(const COLLADAFW::Controller* controller); + + COLLADAFW::UniqueId *get_geometry_uid(const COLLADAFW::UniqueId& controller_uid); + + Object *get_armature_for_joint(COLLADAFW::Node *node); + + void get_rna_path_for_joint(COLLADAFW::Node *node, char *joint_path, size_t count); + + // gives a world-space mat + bool get_joint_bind_mat(float m[][4], COLLADAFW::Node *joint); +}; + +#endif \ No newline at end of file diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp index d10fa4ca94c..c13e089fa4a 100644 --- a/source/blender/collada/DocumentExporter.cpp +++ b/source/blender/collada/DocumentExporter.cpp @@ -91,7 +91,6 @@ extern char build_rev[]; #include "COLLADASWSurfaceInitOption.h" #include "COLLADASWSampler.h" #include "COLLADASWScene.h" -//#include "COLLADASWSurface.h" #include "COLLADASWTechnique.h" #include "COLLADASWTexture.h" #include "COLLADASWLibraryMaterials.h" @@ -112,31 +111,6 @@ extern char build_rev[]; #include #include // std::find -// arithb.c now has QuatToAxisAngle too -#if 0 -// This function assumes that quat is normalized. -// The following document was used as reference: -// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm -void quat_to_axis_angle( float *axis, float *angle,float *q) -{ - // quat to axis angle - *angle = 2 * acos(q[0]); - float divisor = sqrt(1 - q[0] * q[0]); - - // test to avoid divide by zero, divisor is always positive - if (divisor < 0.001f ) { - axis[0] = 1.0f; - axis[1] = 0.0f; - axis[2] = 0.0f; - } - else { - axis[0] = q[1] / divisor; - axis[1] = q[2] / divisor; - axis[2] = q[3] / divisor; - } -} -#endif - char *CustomData_get_layer_name(const struct CustomData *data, int type, int n) { int layer_index = CustomData_get_layer_index(data, type); @@ -2580,8 +2554,8 @@ protected: find_frames(ob, fra, prefix, "rotation_euler"); else if (rotmode == ROT_MODE_QUAT) find_frames(ob, fra, prefix, "rotation_quaternion"); - else if (rotmode == ROT_MODE_AXISANGLE) - ; + /*else if (rotmode == ROT_MODE_AXISANGLE) + ;*/ } // enable fcurves driving a specific bone, disable all the rest diff --git a/source/blender/collada/DocumentExporter.h b/source/blender/collada/DocumentExporter.h index bb6d400fdf1..4aac393b1ab 100644 --- a/source/blender/collada/DocumentExporter.h +++ b/source/blender/collada/DocumentExporter.h @@ -21,6 +21,10 @@ * * ***** END GPL LICENSE BLOCK ***** */ + +#ifndef __DOCUMENTEXPORTER_H__ +#define __DOCUMENTEXPORTER_H__ + struct Scene; class DocumentExporter @@ -29,3 +33,5 @@ class DocumentExporter void exportCurrentScene(Scene *sce, const char* filename); void exportScenes(const char* filename); }; + +#endif diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp index 0b50326ad6c..40e4d389b88 100644 --- a/source/blender/collada/DocumentImporter.cpp +++ b/source/blender/collada/DocumentImporter.cpp @@ -25,3210 +25,74 @@ // * name imported objects // * import object rotation as euler +#include +#include +#include // sort() + +#include +#include + #include "COLLADAFWRoot.h" #include "COLLADAFWIWriter.h" #include "COLLADAFWStableHeaders.h" -#include "COLLADAFWAnimationCurve.h" -#include "COLLADAFWAnimationList.h" #include "COLLADAFWCamera.h" #include "COLLADAFWColorOrTexture.h" #include "COLLADAFWEffect.h" -#include "COLLADAFWFloatOrDoubleArray.h" -#include "COLLADAFWGeometry.h" #include "COLLADAFWImage.h" #include "COLLADAFWIndexList.h" #include "COLLADAFWInstanceGeometry.h" #include "COLLADAFWLight.h" #include "COLLADAFWMaterial.h" -#include "COLLADAFWMesh.h" #include "COLLADAFWMeshPrimitiveWithFaceVertexCount.h" -#include "COLLADAFWNode.h" #include "COLLADAFWPolygons.h" #include "COLLADAFWSampler.h" -#include "COLLADAFWSkinController.h" -#include "COLLADAFWSkinControllerData.h" -#include "COLLADAFWTransformation.h" -#include "COLLADAFWTranslate.h" -#include "COLLADAFWRotate.h" -#include "COLLADAFWScale.h" -#include "COLLADAFWMatrix.h" #include "COLLADAFWTypes.h" #include "COLLADAFWVisualScene.h" -#include "COLLADAFWFileInfo.h" #include "COLLADAFWArrayPrimitiveType.h" #include "COLLADAFWLibraryNodes.h" #include "COLLADASaxFWLLoader.h" -// TODO move "extern C" into header files -extern "C" -{ -#include "ED_keyframing.h" -#include "ED_armature.h" -#include "ED_mesh.h" // ED_vgroup_vert_add, ... -#include "ED_anim_api.h" -#include "ED_object.h" - -#include "WM_types.h" -#include "WM_api.h" - #include "BKE_main.h" -#include "BKE_customdata.h" #include "BKE_library.h" #include "BKE_texture.h" #include "BKE_fcurve.h" #include "BKE_depsgraph.h" #include "BLI_path_util.h" -#include "BKE_displist.h" -#include "BLI_math.h" #include "BKE_scene.h" -} -#include "BKE_armature.h" -#include "BKE_mesh.h" #include "BKE_global.h" -#include "BKE_context.h" #include "BKE_object.h" -#include "BKE_image.h" #include "BKE_material.h" #include "BKE_utildefines.h" -#include "BKE_action.h" +#include "BKE_image.h" -#include "BLI_math.h" #include "BLI_listbase.h" #include "BLI_string.h" -#include "DNA_lamp_types.h" -#include "DNA_armature_types.h" -#include "DNA_anim_types.h" -#include "DNA_curve_types.h" -#include "DNA_texture_types.h" #include "DNA_camera_types.h" -#include "DNA_object_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_mesh_types.h" -#include "DNA_material_types.h" -#include "DNA_scene_types.h" -#include "DNA_modifier_types.h" +#include "DNA_lamp_types.h" #include "MEM_guardedalloc.h" #include "DocumentImporter.h" #include "collada_internal.h" -#include -#include -#include // sort() +#include "TransformReader.h" +#include "AnimationImporter.h" +#include "ArmatureImporter.h" +#include "MeshImporter.h" +#include "collada_utils.h" -#include -#include -// #define COLLADA_DEBUG +/* + COLLADA Importer limitations: + - no multiple scene import, all objects are added to active scene + */ +// #define COLLADA_DEBUG // creates empties for each imported bone on layer 2, for debugging // #define ARMATURE_TEST -char *CustomData_get_layer_name(const struct CustomData *data, int type, int n); - -static const char *primTypeToStr(COLLADAFW::MeshPrimitive::PrimitiveType type) -{ - using namespace COLLADAFW; - - switch (type) { - case MeshPrimitive::LINES: - return "LINES"; - case MeshPrimitive::LINE_STRIPS: - return "LINESTRIPS"; - case MeshPrimitive::POLYGONS: - return "POLYGONS"; - case MeshPrimitive::POLYLIST: - return "POLYLIST"; - case MeshPrimitive::TRIANGLES: - return "TRIANGLES"; - case MeshPrimitive::TRIANGLE_FANS: - return "TRIANGLE_FANS"; - case MeshPrimitive::TRIANGLE_STRIPS: - return "TRIANGLE_FANS"; - case MeshPrimitive::POINTS: - return "POINTS"; - case MeshPrimitive::UNDEFINED_PRIMITIVE_TYPE: - return "UNDEFINED_PRIMITIVE_TYPE"; - } - return "UNKNOWN"; -} - -static const char *geomTypeToStr(COLLADAFW::Geometry::GeometryType type) -{ - switch (type) { - case COLLADAFW::Geometry::GEO_TYPE_MESH: - return "MESH"; - case COLLADAFW::Geometry::GEO_TYPE_SPLINE: - return "SPLINE"; - case COLLADAFW::Geometry::GEO_TYPE_CONVEX_MESH: - return "CONVEX_MESH"; - case COLLADAFW::Geometry::GEO_TYPE_UNKNOWN: - default: - return "UNKNOWN"; - } -} - -// works for COLLADAFW::Node, COLLADAFW::Geometry -template -static const char *get_dae_name(T *node) -{ - const std::string& name = node->getName(); - return name.size() ? name.c_str() : node->getOriginalId().c_str(); -} - -// use this for retrieving bone names, since these must be unique -template -static const char *get_joint_name(T *node) -{ - const std::string& id = node->getOriginalId(); - return id.size() ? id.c_str() : node->getName().c_str(); -} - -static float get_float_value(const COLLADAFW::FloatOrDoubleArray& array, unsigned int index) -{ - if (index >= array.getValuesCount()) - return 0.0f; - - if (array.getType() == COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT) - return array.getFloatValues()->getData()[index]; - else - return array.getDoubleValues()->getData()[index]; -} - -// copied from /editors/object/object_relations.c -static int test_parent_loop(Object *par, Object *ob) -{ - /* test if 'ob' is a parent somewhere in par's parents */ - - if(par == NULL) return 0; - if(ob == par) return 1; - - return test_parent_loop(par->parent, ob); -} - -// a shortened version of parent_set_exec() -// if is_parent_space is true then ob->obmat will be multiplied by par->obmat before parenting -static int set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space=true) -{ - if (!par || test_parent_loop(par, ob)) - return false; - - Object workob; - Main *bmain = CTX_data_main(C); - Scene *sce = CTX_data_scene(C); - - ob->parent = par; - ob->partype = PAROBJECT; - - ob->parsubstr[0] = 0; - - if (is_parent_space) { - // calc par->obmat - where_is_object(sce, par); - - // move child obmat into world space - float mat[4][4]; - mul_m4_m4m4(mat, ob->obmat, par->obmat); - copy_m4_m4(ob->obmat, mat); - } - - // apply child obmat (i.e. decompose it into rot/loc/size) - object_apply_mat4(ob, ob->obmat); - - // compute parentinv - what_does_parent(sce, ob, &workob); - invert_m4_m4(ob->parentinv, workob.obmat); - - ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA; - par->recalc |= OB_RECALC_OB; - - DAG_scene_sort(bmain, sce); - DAG_ids_flush_update(bmain, 0); - WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); - - return true; -} - -typedef std::map > TexIndexTextureArrayMap; - -class TransformReader : public TransformBase -{ -protected: - - UnitConverter *unit_converter; - - struct Animation { - Object *ob; - COLLADAFW::Node *node; - COLLADAFW::Transformation *tm; // which transform is animated by an AnimationList->id - }; - -public: - - TransformReader(UnitConverter* conv) : unit_converter(conv) {} - - void get_node_mat(float mat[][4], COLLADAFW::Node *node, std::map *animation_map, - Object *ob) - { - float cur[4][4]; - float copy[4][4]; - - unit_m4(mat); - - for (unsigned int i = 0; i < node->getTransformations().getCount(); i++) { - - COLLADAFW::Transformation *tm = node->getTransformations()[i]; - COLLADAFW::Transformation::TransformationType type = tm->getTransformationType(); - - switch(type) { - case COLLADAFW::Transformation::TRANSLATE: - dae_translate_to_mat4(tm, cur); - break; - case COLLADAFW::Transformation::ROTATE: - dae_rotate_to_mat4(tm, cur); - break; - case COLLADAFW::Transformation::SCALE: - dae_scale_to_mat4(tm, cur); - break; - case COLLADAFW::Transformation::MATRIX: - dae_matrix_to_mat4(tm, cur); - break; - case COLLADAFW::Transformation::LOOKAT: - case COLLADAFW::Transformation::SKEW: - fprintf(stderr, "LOOKAT and SKEW transformations are not supported yet.\n"); - break; - } - - copy_m4_m4(copy, mat); - mul_m4_m4m4(mat, cur, copy); - - if (animation_map) { - // AnimationList that drives this Transformation - const COLLADAFW::UniqueId& anim_list_id = tm->getAnimationList(); - - // store this so later we can link animation data with ob - Animation anim = {ob, node, tm}; - (*animation_map)[anim_list_id] = anim; - } - } - } - - void dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[][4]) - { - COLLADAFW::Rotate *ro = (COLLADAFW::Rotate*)tm; - COLLADABU::Math::Vector3& axis = ro->getRotationAxis(); - float angle = (float)(ro->getRotationAngle() * M_PI / 180.0f); - float ax[] = {axis[0], axis[1], axis[2]}; - // float quat[4]; - // axis_angle_to_quat(quat, axis, angle); - // quat_to_mat4(m, quat); - axis_angle_to_mat4(m, ax, angle); - } - - void dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[][4]) - { - COLLADAFW::Translate *tra = (COLLADAFW::Translate*)tm; - COLLADABU::Math::Vector3& t = tra->getTranslation(); - - unit_m4(m); - - m[3][0] = (float)t[0]; - m[3][1] = (float)t[1]; - m[3][2] = (float)t[2]; - } - - void dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[][4]) - { - COLLADABU::Math::Vector3& s = ((COLLADAFW::Scale*)tm)->getScale(); - float size[3] = {(float)s[0], (float)s[1], (float)s[2]}; - size_to_mat4(m, size); - } - - void dae_matrix_to_mat4(COLLADAFW::Transformation *tm, float m[][4]) - { - unit_converter->dae_matrix_to_mat4(m, ((COLLADAFW::Matrix*)tm)->getMatrix()); - } - - void dae_translate_to_v3(COLLADAFW::Transformation *tm, float v[3]) - { - dae_vector3_to_v3(((COLLADAFW::Translate*)tm)->getTranslation(), v); - } - - void dae_scale_to_v3(COLLADAFW::Transformation *tm, float v[3]) - { - dae_vector3_to_v3(((COLLADAFW::Scale*)tm)->getScale(), v); - } - - void dae_vector3_to_v3(const COLLADABU::Math::Vector3 &v3, float v[3]) - { - v[0] = v3.x; - v[1] = v3.y; - v[2] = v3.z; - } -}; - -// only for ArmatureImporter to "see" MeshImporter::get_object_by_geom_uid -class MeshImporterBase -{ -public: - virtual Object *get_object_by_geom_uid(const COLLADAFW::UniqueId& geom_uid) = 0; -}; - -// ditto as above -class AnimationImporterBase -{ -public: - // virtual void change_eul_to_quat(Object *ob, bAction *act) = 0; -}; - -class ArmatureImporter : private TransformReader -{ -private: - Scene *scene; - UnitConverter *unit_converter; - - // std::map joint_index_to_joint_info_map; - // std::map joint_id_to_joint_index_map; - - struct LeafBone { - // COLLADAFW::Node *node; - EditBone *bone; - char name[32]; - float mat[4][4]; // bone matrix, derived from inv_bind_mat - }; - std::vector leaf_bones; - // int bone_direction_row; // XXX not used - float leaf_bone_length; - int totbone; - // XXX not used - // float min_angle; // minimum angle between bone head-tail and a row of bone matrix - -#if 0 - struct ArmatureJoints { - Object *ob_arm; - std::vector root_joints; - }; - std::vector armature_joints; -#endif - - Object *empty; // empty for leaf bones - - std::map geom_uid_by_controller_uid; - std::map joint_by_uid; // contains all joints - std::vector root_joints; - std::map joint_parent_map; - - MeshImporterBase *mesh_importer; - AnimationImporterBase *anim_importer; - - // This is used to store data passed in write_controller_data. - // Arrays from COLLADAFW::SkinControllerData lose ownership, so do this class members - // so that arrays don't get freed until we free them explicitly. - class SkinInfo - { - private: - // to build armature bones from inverse bind matrices - struct JointData { - float inv_bind_mat[4][4]; // joint inverse bind matrix - COLLADAFW::UniqueId joint_uid; // joint node UID - // Object *ob_arm; // armature object - }; - - float bind_shape_matrix[4][4]; - - // data from COLLADAFW::SkinControllerData, each array should be freed - COLLADAFW::UIntValuesArray joints_per_vertex; - COLLADAFW::UIntValuesArray weight_indices; - COLLADAFW::IntValuesArray joint_indices; - // COLLADAFW::FloatOrDoubleArray weights; - std::vector weights; - - std::vector joint_data; // index to this vector is joint index - - UnitConverter *unit_converter; - - Object *ob_arm; - COLLADAFW::UniqueId controller_uid; - Object *parent; - - public: - - SkinInfo() {} - - SkinInfo(const SkinInfo& skin) : weights(skin.weights), - joint_data(skin.joint_data), - unit_converter(skin.unit_converter), - ob_arm(skin.ob_arm), - controller_uid(skin.controller_uid), - parent(skin.parent) - { - copy_m4_m4(bind_shape_matrix, (float (*)[4])skin.bind_shape_matrix); - - transfer_uint_array_data_const(skin.joints_per_vertex, joints_per_vertex); - transfer_uint_array_data_const(skin.weight_indices, weight_indices); - transfer_int_array_data_const(skin.joint_indices, joint_indices); - } - - SkinInfo(UnitConverter *conv) : unit_converter(conv), ob_arm(NULL), parent(NULL) {} - - // nobody owns the data after this, so it should be freed manually with releaseMemory - template - void transfer_array_data(T& src, T& dest) - { - dest.setData(src.getData(), src.getCount()); - src.yieldOwnerShip(); - dest.yieldOwnerShip(); - } - - // when src is const we cannot src.yieldOwnerShip, this is used by copy constructor - void transfer_int_array_data_const(const COLLADAFW::IntValuesArray& src, COLLADAFW::IntValuesArray& dest) - { - dest.setData((int*)src.getData(), src.getCount()); - dest.yieldOwnerShip(); - } - - void transfer_uint_array_data_const(const COLLADAFW::UIntValuesArray& src, COLLADAFW::UIntValuesArray& dest) - { - dest.setData((unsigned int*)src.getData(), src.getCount()); - dest.yieldOwnerShip(); - } - - void borrow_skin_controller_data(const COLLADAFW::SkinControllerData* skin) - { - transfer_array_data((COLLADAFW::UIntValuesArray&)skin->getJointsPerVertex(), joints_per_vertex); - transfer_array_data((COLLADAFW::UIntValuesArray&)skin->getWeightIndices(), weight_indices); - transfer_array_data((COLLADAFW::IntValuesArray&)skin->getJointIndices(), joint_indices); - // transfer_array_data(skin->getWeights(), weights); - - // cannot transfer data for FloatOrDoubleArray, copy values manually - const COLLADAFW::FloatOrDoubleArray& weight = skin->getWeights(); - for (unsigned int i = 0; i < weight.getValuesCount(); i++) - weights.push_back(get_float_value(weight, i)); - - unit_converter->dae_matrix_to_mat4(bind_shape_matrix, skin->getBindShapeMatrix()); - } - - void free() - { - joints_per_vertex.releaseMemory(); - weight_indices.releaseMemory(); - joint_indices.releaseMemory(); - // weights.releaseMemory(); - } - - // using inverse bind matrices to construct armature - // it is safe to invert them to get the original matrices - // because if they are inverse matrices, they can be inverted - void add_joint(const COLLADABU::Math::Matrix4& matrix) - { - JointData jd; - unit_converter->dae_matrix_to_mat4(jd.inv_bind_mat, matrix); - joint_data.push_back(jd); - } - - void set_controller(const COLLADAFW::SkinController* co) - { - controller_uid = co->getUniqueId(); - - // fill in joint UIDs - const COLLADAFW::UniqueIdArray& joint_uids = co->getJoints(); - for (unsigned int i = 0; i < joint_uids.getCount(); i++) { - joint_data[i].joint_uid = joint_uids[i]; - - // // store armature pointer - // JointData& jd = joint_index_to_joint_info_map[i]; - // jd.ob_arm = ob_arm; - - // now we'll be able to get inv bind matrix from joint id - // joint_id_to_joint_index_map[joint_ids[i]] = i; - } - } - - // called from write_controller - Object *create_armature(Scene *scene) - { - ob_arm = add_object(scene, OB_ARMATURE); - return ob_arm; - } - - Object* set_armature(Object *ob_arm) - { - if (this->ob_arm) - return this->ob_arm; - - this->ob_arm = ob_arm; - return ob_arm; - } - - bool get_joint_inv_bind_matrix(float inv_bind_mat[][4], COLLADAFW::Node *node) - { - const COLLADAFW::UniqueId& uid = node->getUniqueId(); - std::vector::iterator it; - for (it = joint_data.begin(); it != joint_data.end(); it++) { - if ((*it).joint_uid == uid) { - copy_m4_m4(inv_bind_mat, (*it).inv_bind_mat); - return true; - } - } - - return false; - } - - Object *get_armature() - { - return ob_arm; - } - - const COLLADAFW::UniqueId& get_controller_uid() - { - return controller_uid; - } - - // check if this skin controller references a joint or any descendant of it - // - // some nodes may not be referenced by SkinController, - // in this case to determine if the node belongs to this armature, - // we need to search down the tree - bool uses_joint_or_descendant(COLLADAFW::Node *node) - { - const COLLADAFW::UniqueId& uid = node->getUniqueId(); - std::vector::iterator it; - for (it = joint_data.begin(); it != joint_data.end(); it++) { - if ((*it).joint_uid == uid) - return true; - } - - COLLADAFW::NodePointerArray& children = node->getChildNodes(); - for (unsigned int i = 0; i < children.getCount(); i++) { - if (uses_joint_or_descendant(children[i])) - return true; - } - - return false; - } - - void link_armature(bContext *C, Object *ob, std::map& joint_by_uid, - TransformReader *tm) - { - Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - - ModifierData *md = ED_object_modifier_add(NULL, bmain, scene, ob, NULL, eModifierType_Armature); - ((ArmatureModifierData *)md)->object = ob_arm; - - copy_m4_m4(ob->obmat, bind_shape_matrix); - object_apply_mat4(ob, ob->obmat); -#if 1 - ::set_parent(ob, ob_arm, C); -#else - Object workob; - ob->parent = ob_arm; - ob->partype = PAROBJECT; - - what_does_parent(scene, ob, &workob); - invert_m4_m4(ob->parentinv, workob.obmat); - - ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA; - - DAG_scene_sort(bmain, scene); - DAG_ids_flush_update(bmain, 0); - WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); -#endif - - ((bArmature*)ob_arm->data)->deformflag = ARM_DEF_VGROUP; - - // create all vertex groups - std::vector::iterator it; - int joint_index; - for (it = joint_data.begin(), joint_index = 0; it != joint_data.end(); it++, joint_index++) { - const char *name = "Group"; - - // name group by joint node name - if (joint_by_uid.find((*it).joint_uid) != joint_by_uid.end()) { - name = get_joint_name(joint_by_uid[(*it).joint_uid]); - } - - ED_vgroup_add_name(ob, (char*)name); - } - - // - number of joints per vertex - joints_per_vertex - // - [[bone index, weight index] * joints per vertex] * vertices - weight indices - // ^ bone index can be -1 meaning weight toward bind shape, how to express this in Blender? - - // for each vertex in weight indices - // for each bone index in vertex - // add vertex to group at group index - // treat group index -1 specially - - // get def group by index with BLI_findlink - - for (unsigned int vertex = 0, weight = 0; vertex < joints_per_vertex.getCount(); vertex++) { - - unsigned int limit = weight + joints_per_vertex[vertex]; - for ( ; weight < limit; weight++) { - int joint = joint_indices[weight], joint_weight = weight_indices[weight]; - - // -1 means "weight towards the bind shape", we just don't assign it to any group - if (joint != -1) { - bDeformGroup *def = (bDeformGroup*)BLI_findlink(&ob->defbase, joint); - - ED_vgroup_vert_add(ob, def, vertex, weights[joint_weight], WEIGHT_REPLACE); - } - } - } - } - - bPoseChannel *get_pose_channel_from_node(COLLADAFW::Node *node) - { - return get_pose_channel(ob_arm->pose, get_joint_name(node)); - } - - void set_parent(Object *_parent) - { - parent = _parent; - } - - Object* get_parent() - { - return parent; - } - - void find_root_joints(const std::vector &root_joints, - std::map& joint_by_uid, - std::vector& result) - { - std::vector::const_iterator it; - for (it = root_joints.begin(); it != root_joints.end(); it++) { - COLLADAFW::Node *root = *it; - std::vector::iterator ji; - for (ji = joint_data.begin(); ji != joint_data.end(); ji++) { - COLLADAFW::Node *joint = joint_by_uid[(*ji).joint_uid]; - if (find_node_in_tree(joint, root)) { - if (std::find(result.begin(), result.end(), root) == result.end()) - result.push_back(root); - } - } - } - } - - bool find_node_in_tree(COLLADAFW::Node *node, COLLADAFW::Node *tree_root) - { - if (node == tree_root) - return true; - - COLLADAFW::NodePointerArray& children = tree_root->getChildNodes(); - for (unsigned int i = 0; i < children.getCount(); i++) { - if (find_node_in_tree(node, children[i])) - return true; - } - - return false; - } - - }; - - std::map skin_by_data_uid; // data UID = skin controller data UID -#if 0 - JointData *get_joint_data(COLLADAFW::Node *node) - { - const COLLADAFW::UniqueId& joint_id = node->getUniqueId(); - - if (joint_id_to_joint_index_map.find(joint_id) == joint_id_to_joint_index_map.end()) { - fprintf(stderr, "Cannot find a joint index by joint id for %s.\n", - node->getOriginalId().c_str()); - return NULL; - } - - int joint_index = joint_id_to_joint_index_map[joint_id]; - - return &joint_index_to_joint_info_map[joint_index]; - } -#endif - - void create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBone *parent, int totchild, - float parent_mat[][4], bArmature *arm) - { - float joint_inv_bind_mat[4][4]; - - // JointData* jd = get_joint_data(node); - - float mat[4][4]; - - if (skin.get_joint_inv_bind_matrix(joint_inv_bind_mat, node)) { - // get original world-space matrix - invert_m4_m4(mat, joint_inv_bind_mat); - } - // create a bone even if there's no joint data for it (i.e. it has no influence) - else { - float obmat[4][4]; - - // object-space - get_node_mat(obmat, node, NULL, NULL); - - // get world-space - if (parent) - mul_m4_m4m4(mat, obmat, parent_mat); - else - copy_m4_m4(mat, obmat); - } - - // TODO rename from Node "name" attrs later - EditBone *bone = ED_armature_edit_bone_add(arm, (char*)get_joint_name(node)); - totbone++; - - if (parent) bone->parent = parent; - - // set head - copy_v3_v3(bone->head, mat[3]); - - // set tail, don't set it to head because 0-length bones are not allowed - float vec[3] = {0.0f, 0.5f, 0.0f}; - add_v3_v3v3(bone->tail, bone->head, vec); - - // set parent tail - if (parent && totchild == 1) { - copy_v3_v3(parent->tail, bone->head); - - // not setting BONE_CONNECTED because this would lock child bone location with respect to parent - // bone->flag |= BONE_CONNECTED; - - // XXX increase this to prevent "very" small bones? - const float epsilon = 0.000001f; - - // derive leaf bone length - float length = len_v3v3(parent->head, parent->tail); - if ((length < leaf_bone_length || totbone == 0) && length > epsilon) { - leaf_bone_length = length; - } - - // treat zero-sized bone like a leaf bone - if (length <= epsilon) { - add_leaf_bone(parent_mat, parent); - } - - /* -#if 0 - // and which row in mat is bone direction - float vec[3]; - sub_v3_v3v3(vec, parent->tail, parent->head); -#ifdef COLLADA_DEBUG - print_v3("tail - head", vec); - print_m4("matrix", parent_mat); -#endif - for (int i = 0; i < 3; i++) { -#ifdef COLLADA_DEBUG - char *axis_names[] = {"X", "Y", "Z"}; - printf("%s-axis length is %f\n", axis_names[i], len_v3(parent_mat[i])); -#endif - float angle = angle_v2v2(vec, parent_mat[i]); - if (angle < min_angle) { -#ifdef COLLADA_DEBUG - print_v3("picking", parent_mat[i]); - printf("^ %s axis of %s's matrix\n", axis_names[i], get_dae_name(node)); -#endif - bone_direction_row = i; - min_angle = angle; - } - } -#endif - */ - } - - COLLADAFW::NodePointerArray& children = node->getChildNodes(); - for (unsigned int i = 0; i < children.getCount(); i++) { - create_bone(skin, children[i], bone, children.getCount(), mat, arm); - } - - // in second case it's not a leaf bone, but we handle it the same way - if (!children.getCount() || children.getCount() > 1) { - add_leaf_bone(mat, bone); - } - } - - void add_leaf_bone(float mat[][4], EditBone *bone) - { - LeafBone leaf; - - leaf.bone = bone; - copy_m4_m4(leaf.mat, mat); - BLI_strncpy(leaf.name, bone->name, sizeof(leaf.name)); - - leaf_bones.push_back(leaf); - } - - void fix_leaf_bones() - { - // just setting tail for leaf bones here - - std::vector::iterator it; - for (it = leaf_bones.begin(); it != leaf_bones.end(); it++) { - LeafBone& leaf = *it; - - // pointing up - float vec[3] = {0.0f, 0.0f, 1.0f}; - - mul_v3_fl(vec, leaf_bone_length); - - copy_v3_v3(leaf.bone->tail, leaf.bone->head); - add_v3_v3v3(leaf.bone->tail, leaf.bone->head, vec); - } - } - - void set_leaf_bone_shapes(Object *ob_arm) - { - bPose *pose = ob_arm->pose; - - std::vector::iterator it; - for (it = leaf_bones.begin(); it != leaf_bones.end(); it++) { - LeafBone& leaf = *it; - - bPoseChannel *pchan = get_pose_channel(pose, leaf.name); - if (pchan) { - pchan->custom = get_empty_for_leaves(); - } - else { - fprintf(stderr, "Cannot find a pose channel for leaf bone %s\n", leaf.name); - } - } - } - -#if 0 - void set_euler_rotmode() - { - // just set rotmode = ROT_MODE_EUL on pose channel for each joint - - std::map::iterator it; - - for (it = joint_by_uid.begin(); it != joint_by_uid.end(); it++) { - - COLLADAFW::Node *joint = it->second; - - std::map::iterator sit; - - for (sit = skin_by_data_uid.begin(); sit != skin_by_data_uid.end(); sit++) { - SkinInfo& skin = sit->second; - - if (skin.uses_joint_or_descendant(joint)) { - bPoseChannel *pchan = skin.get_pose_channel_from_node(joint); - - if (pchan) { - pchan->rotmode = ROT_MODE_EUL; - } - else { - fprintf(stderr, "Cannot find pose channel for %s.\n", get_joint_name(joint)); - } - - break; - } - } - } - } -#endif - - Object *get_empty_for_leaves() - { - if (empty) return empty; - - empty = add_object(scene, OB_EMPTY); - empty->empty_drawtype = OB_EMPTY_SPHERE; - - return empty; - } - -#if 0 - Object *find_armature(COLLADAFW::Node *node) - { - JointData* jd = get_joint_data(node); - if (jd) return jd->ob_arm; - - COLLADAFW::NodePointerArray& children = node->getChildNodes(); - for (int i = 0; i < children.getCount(); i++) { - Object *ob_arm = find_armature(children[i]); - if (ob_arm) return ob_arm; - } - - return NULL; - } - - ArmatureJoints& get_armature_joints(Object *ob_arm) - { - // try finding it - std::vector::iterator it; - for (it = armature_joints.begin(); it != armature_joints.end(); it++) { - if ((*it).ob_arm == ob_arm) return *it; - } - - // not found, create one - ArmatureJoints aj; - aj.ob_arm = ob_arm; - armature_joints.push_back(aj); - - return armature_joints.back(); - } -#endif - - void create_armature_bones(SkinInfo& skin) - { - // just do like so: - // - get armature - // - enter editmode - // - add edit bones and head/tail properties using matrices and parent-child info - // - exit edit mode - // - set a sphere shape to leaf bones - - Object *ob_arm = NULL; - - /* - * find if there's another skin sharing at least one bone with this skin - * if so, use that skin's armature - */ - - /* - Pseudocode: - - find_node_in_tree(node, root_joint) - - skin::find_root_joints(root_joints): - std::vector root_joints; - for each root in root_joints: - for each joint in joints: - if find_node_in_tree(joint, root): - if (std::find(root_joints.begin(), root_joints.end(), root) == root_joints.end()) - root_joints.push_back(root); - - for (each skin B with armature) { - find all root joints for skin B - - for each joint X in skin A: - for each root joint R in skin B: - if (find_node_in_tree(X, R)) { - shared = 1; - goto endloop; - } - } - - endloop: - */ - - SkinInfo *a = &skin; - Object *shared = NULL; - std::vector skin_root_joints; - - std::map::iterator it; - for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) { - SkinInfo *b = &it->second; - if (b == a || b->get_armature() == NULL) - continue; - - skin_root_joints.clear(); - - b->find_root_joints(root_joints, joint_by_uid, skin_root_joints); - - std::vector::iterator ri; - for (ri = skin_root_joints.begin(); ri != skin_root_joints.end(); ri++) { - if (a->uses_joint_or_descendant(*ri)) { - shared = b->get_armature(); - break; - } - } - - if (shared != NULL) - break; - } - - if (shared) - ob_arm = skin.set_armature(shared); - else - ob_arm = skin.create_armature(scene); - - // enter armature edit mode - ED_armature_to_edit(ob_arm); - - leaf_bones.clear(); - totbone = 0; - // bone_direction_row = 1; // TODO: don't default to Y but use asset and based on it decide on default row - leaf_bone_length = 0.1f; - // min_angle = 360.0f; // minimum angle between bone head-tail and a row of bone matrix - - // create bones - /* - TODO: - check if bones have already been created for a given joint - */ - - std::vector::iterator ri; - for (ri = root_joints.begin(); ri != root_joints.end(); ri++) { - // for shared armature check if bone tree is already created - if (shared && std::find(skin_root_joints.begin(), skin_root_joints.end(), *ri) != skin_root_joints.end()) - continue; - - // since root_joints may contain joints for multiple controllers, we need to filter - if (skin.uses_joint_or_descendant(*ri)) { - create_bone(skin, *ri, NULL, (*ri)->getChildNodes().getCount(), NULL, (bArmature*)ob_arm->data); - - if (joint_parent_map.find((*ri)->getUniqueId()) != joint_parent_map.end() && !skin.get_parent()) - skin.set_parent(joint_parent_map[(*ri)->getUniqueId()]); - } - } - - fix_leaf_bones(); - - // exit armature edit mode - ED_armature_from_edit(ob_arm); - ED_armature_edit_free(ob_arm); - DAG_id_flush_update(&ob_arm->id, OB_RECALC_OB|OB_RECALC_DATA); - - set_leaf_bone_shapes(ob_arm); - - // set_euler_rotmode(); - } - - -public: - - ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, AnimationImporterBase *anim, Scene *sce) : - TransformReader(conv), scene(sce), empty(NULL), mesh_importer(mesh), anim_importer(anim) {} - - ~ArmatureImporter() - { - // free skin controller data if we forget to do this earlier - std::map::iterator it; - for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) { - it->second.free(); - } - } - - // root - if this joint is the top joint in hierarchy, if a joint - // is a child of a node (not joint), root should be true since - // this is where we build armature bones from - void add_joint(COLLADAFW::Node *node, bool root, Object *parent) - { - joint_by_uid[node->getUniqueId()] = node; - if (root) { - root_joints.push_back(node); - - if (parent) - joint_parent_map[node->getUniqueId()] = parent; - } - } - -#if 0 - void add_root_joint(COLLADAFW::Node *node) - { - // root_joints.push_back(node); - Object *ob_arm = find_armature(node); - if (ob_arm) { - get_armature_joints(ob_arm).root_joints.push_back(node); - } -#ifdef COLLADA_DEBUG - else { - fprintf(stderr, "%s cannot be added to armature.\n", get_joint_name(node)); - } -#endif - } -#endif - - // here we add bones to armatures, having armatures previously created in write_controller - void make_armatures(bContext *C) - { - std::map::iterator it; - for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) { - - SkinInfo& skin = it->second; - - create_armature_bones(skin); - - // link armature with a mesh object - Object *ob = mesh_importer->get_object_by_geom_uid(*get_geometry_uid(skin.get_controller_uid())); - if (ob) - skin.link_armature(C, ob, joint_by_uid, this); - else - fprintf(stderr, "Cannot find object to link armature with.\n"); - - // set armature parent if any - Object *par = skin.get_parent(); - if (par) - set_parent(skin.get_armature(), par, C, false); - - // free memory stolen from SkinControllerData - skin.free(); - } - } - -#if 0 - // link with meshes, create vertex groups, assign weights - void link_armature(Object *ob_arm, const COLLADAFW::UniqueId& geom_id, const COLLADAFW::UniqueId& controller_data_id) - { - Object *ob = mesh_importer->get_object_by_geom_uid(geom_id); - - if (!ob) { - fprintf(stderr, "Cannot find object by geometry UID.\n"); - return; - } - - if (skin_by_data_uid.find(controller_data_id) == skin_by_data_uid.end()) { - fprintf(stderr, "Cannot find skin info by controller data UID.\n"); - return; - } - - SkinInfo& skin = skin_by_data_uid[conroller_data_id]; - - // create vertex groups - } -#endif - - bool write_skin_controller_data(const COLLADAFW::SkinControllerData* data) - { - // at this stage we get vertex influence info that should go into me->verts and ob->defbase - // there's no info to which object this should be long so we associate it with skin controller data UID - - // don't forget to call defgroup_unique_name before we copy - - // controller data uid -> [armature] -> joint data, - // [mesh object] - // - - SkinInfo skin(unit_converter); - skin.borrow_skin_controller_data(data); - - // store join inv bind matrix to use it later in armature construction - const COLLADAFW::Matrix4Array& inv_bind_mats = data->getInverseBindMatrices(); - for (unsigned int i = 0; i < data->getJointsCount(); i++) { - skin.add_joint(inv_bind_mats[i]); - } - - skin_by_data_uid[data->getUniqueId()] = skin; - - return true; - } - - bool write_controller(const COLLADAFW::Controller* controller) - { - // - create and store armature object - - const COLLADAFW::UniqueId& skin_id = controller->getUniqueId(); - - if (controller->getControllerType() == COLLADAFW::Controller::CONTROLLER_TYPE_SKIN) { - COLLADAFW::SkinController *co = (COLLADAFW::SkinController*)controller; - // to be able to find geom id by controller id - geom_uid_by_controller_uid[skin_id] = co->getSource(); - - const COLLADAFW::UniqueId& data_uid = co->getSkinControllerData(); - if (skin_by_data_uid.find(data_uid) == skin_by_data_uid.end()) { - fprintf(stderr, "Cannot find skin by controller data UID.\n"); - return true; - } - - skin_by_data_uid[data_uid].set_controller(co); - } - // morph controller - else { - // shape keys? :) - fprintf(stderr, "Morph controller is not supported yet.\n"); - } - - return true; - } - - COLLADAFW::UniqueId *get_geometry_uid(const COLLADAFW::UniqueId& controller_uid) - { - if (geom_uid_by_controller_uid.find(controller_uid) == geom_uid_by_controller_uid.end()) - return NULL; - - return &geom_uid_by_controller_uid[controller_uid]; - } - - Object *get_armature_for_joint(COLLADAFW::Node *node) - { - std::map::iterator it; - for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) { - SkinInfo& skin = it->second; - - if (skin.uses_joint_or_descendant(node)) - return skin.get_armature(); - } - - return NULL; - } - - void get_rna_path_for_joint(COLLADAFW::Node *node, char *joint_path, size_t count) - { - BLI_snprintf(joint_path, count, "pose.bones[\"%s\"]", get_joint_name(node)); - } - - // gives a world-space mat - bool get_joint_bind_mat(float m[][4], COLLADAFW::Node *joint) - { - std::map::iterator it; - bool found = false; - for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) { - SkinInfo& skin = it->second; - if ((found = skin.get_joint_inv_bind_matrix(m, joint))) { - invert_m4(m); - break; - } - } - - return found; - } -}; - -class MeshImporter : public MeshImporterBase -{ -private: - - Scene *scene; - ArmatureImporter *armature_importer; - - std::map uid_mesh_map; // geometry unique id-to-mesh map - std::map uid_object_map; // geom uid-to-object - // this structure is used to assign material indices to faces - // it holds a portion of Mesh faces and corresponds to a DAE primitive list (, , etc.) - struct Primitive { - MFace *mface; - unsigned int totface; - }; - typedef std::map > MaterialIdPrimitiveArrayMap; - std::map geom_uid_mat_mapping_map; // crazy name! - - class UVDataWrapper - { - COLLADAFW::MeshVertexData *mVData; - public: - UVDataWrapper(COLLADAFW::MeshVertexData& vdata) : mVData(&vdata) - {} - -#ifdef COLLADA_DEBUG - void print() - { - fprintf(stderr, "UVs:\n"); - switch(mVData->getType()) { - case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: - { - COLLADAFW::ArrayPrimitiveType* values = mVData->getFloatValues(); - if (values->getCount()) { - for (int i = 0; i < values->getCount(); i += 2) { - fprintf(stderr, "%.1f, %.1f\n", (*values)[i], (*values)[i+1]); - } - } - } - break; - case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE: - { - COLLADAFW::ArrayPrimitiveType* values = mVData->getDoubleValues(); - if (values->getCount()) { - for (int i = 0; i < values->getCount(); i += 2) { - fprintf(stderr, "%.1f, %.1f\n", (float)(*values)[i], (float)(*values)[i+1]); - } - } - } - break; - } - fprintf(stderr, "\n"); - } -#endif - - void getUV(int uv_index[2], float *uv) - { - switch(mVData->getType()) { - case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: - { - COLLADAFW::ArrayPrimitiveType* values = mVData->getFloatValues(); - if (values->empty()) return; - uv[0] = (*values)[uv_index[0]]; - uv[1] = (*values)[uv_index[1]]; - - } - break; - case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE: - { - COLLADAFW::ArrayPrimitiveType* values = mVData->getDoubleValues(); - if (values->empty()) return; - uv[0] = (float)(*values)[uv_index[0]]; - uv[1] = (float)(*values)[uv_index[1]]; - - } - break; - case COLLADAFW::MeshVertexData::DATA_TYPE_UNKNOWN: - default: - fprintf(stderr, "MeshImporter.getUV(): unknown data type\n"); - } - } - }; - - void set_face_indices(MFace *mface, unsigned int *indices, bool quad) - { - mface->v1 = indices[0]; - mface->v2 = indices[1]; - mface->v3 = indices[2]; - if (quad) mface->v4 = indices[3]; - else mface->v4 = 0; -#ifdef COLLADA_DEBUG - // fprintf(stderr, "%u, %u, %u \n", indices[0], indices[1], indices[2]); -#endif - } - - // not used anymore, test_index_face from blenkernel is better -#if 0 - // change face indices order so that v4 is not 0 - void rotate_face_indices(MFace *mface) { - mface->v4 = mface->v1; - mface->v1 = mface->v2; - mface->v2 = mface->v3; - mface->v3 = 0; - } -#endif - - void set_face_uv(MTFace *mtface, UVDataWrapper &uvs, - COLLADAFW::IndexList& index_list, unsigned int *tris_indices) - { - int uv_indices[4][2]; - - // per face vertex indices, this means for quad we have 4 indices, not 8 - COLLADAFW::UIntValuesArray& indices = index_list.getIndices(); - - // make indices into FloatOrDoubleArray - for (int i = 0; i < 3; i++) { - int uv_index = indices[tris_indices[i]]; - uv_indices[i][0] = uv_index * 2; - uv_indices[i][1] = uv_index * 2 + 1; - } - - uvs.getUV(uv_indices[0], mtface->uv[0]); - uvs.getUV(uv_indices[1], mtface->uv[1]); - uvs.getUV(uv_indices[2], mtface->uv[2]); - } - - void set_face_uv(MTFace *mtface, UVDataWrapper &uvs, - COLLADAFW::IndexList& index_list, int index, bool quad) - { - int uv_indices[4][2]; - - // per face vertex indices, this means for quad we have 4 indices, not 8 - COLLADAFW::UIntValuesArray& indices = index_list.getIndices(); - - // make indices into FloatOrDoubleArray - for (int i = 0; i < (quad ? 4 : 3); i++) { - int uv_index = indices[index + i]; - uv_indices[i][0] = uv_index * 2; - uv_indices[i][1] = uv_index * 2 + 1; - } - - uvs.getUV(uv_indices[0], mtface->uv[0]); - uvs.getUV(uv_indices[1], mtface->uv[1]); - uvs.getUV(uv_indices[2], mtface->uv[2]); - - if (quad) uvs.getUV(uv_indices[3], mtface->uv[3]); - -#ifdef COLLADA_DEBUG - /*if (quad) { - fprintf(stderr, "face uv:\n" - "((%d, %d), (%d, %d), (%d, %d), (%d, %d))\n" - "((%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f))\n", - - uv_indices[0][0], uv_indices[0][1], - uv_indices[1][0], uv_indices[1][1], - uv_indices[2][0], uv_indices[2][1], - uv_indices[3][0], uv_indices[3][1], - - mtface->uv[0][0], mtface->uv[0][1], - mtface->uv[1][0], mtface->uv[1][1], - mtface->uv[2][0], mtface->uv[2][1], - mtface->uv[3][0], mtface->uv[3][1]); - } - else { - fprintf(stderr, "face uv:\n" - "((%d, %d), (%d, %d), (%d, %d))\n" - "((%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f))\n", - - uv_indices[0][0], uv_indices[0][1], - uv_indices[1][0], uv_indices[1][1], - uv_indices[2][0], uv_indices[2][1], - - mtface->uv[0][0], mtface->uv[0][1], - mtface->uv[1][0], mtface->uv[1][1], - mtface->uv[2][0], mtface->uv[2][1]); - }*/ -#endif - } - -#ifdef COLLADA_DEBUG - void print_index_list(COLLADAFW::IndexList& index_list) - { - fprintf(stderr, "Index list for \"%s\":\n", index_list.getName().c_str()); - for (int i = 0; i < index_list.getIndicesCount(); i += 2) { - fprintf(stderr, "%u, %u\n", index_list.getIndex(i), index_list.getIndex(i + 1)); - } - fprintf(stderr, "\n"); - } -#endif - - bool is_nice_mesh(COLLADAFW::Mesh *mesh) - { - COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives(); - - const char *name = get_dae_name(mesh); - - for (unsigned i = 0; i < prim_arr.getCount(); i++) { - - COLLADAFW::MeshPrimitive *mp = prim_arr[i]; - COLLADAFW::MeshPrimitive::PrimitiveType type = mp->getPrimitiveType(); - - const char *type_str = primTypeToStr(type); - - // OpenCollada passes POLYGONS type for - if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) { - - COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons*)mp; - COLLADAFW::Polygons::VertexCountArray& vca = mpvc->getGroupedVerticesVertexCountArray(); - - for(unsigned int j = 0; j < vca.getCount(); j++){ - int count = vca[j]; - if (count < 3) { - fprintf(stderr, "Primitive %s in %s has at least one face with vertex count < 3\n", - type_str, name); - return false; - } - } - - } - else if(type != COLLADAFW::MeshPrimitive::TRIANGLES) { - fprintf(stderr, "Primitive type %s is not supported.\n", type_str); - return false; - } - } - - if (mesh->getPositions().empty()) { - fprintf(stderr, "Mesh %s has no vertices.\n", name); - return false; - } - - return true; - } - - void read_vertices(COLLADAFW::Mesh *mesh, Mesh *me) - { - // vertices - me->totvert = mesh->getPositions().getFloatValues()->getCount() / 3; - me->mvert = (MVert*)CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert); - - COLLADAFW::MeshVertexData& pos = mesh->getPositions(); - MVert *mvert; - int i; - - for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) - get_vector(mvert->co, pos, i); - } - - int triangulate_poly(unsigned int *indices, int totvert, MVert *verts, std::vector& tri) - { - ListBase dispbase; - DispList *dl; - float *vert; - int i = 0; - - dispbase.first = dispbase.last = NULL; - - dl = (DispList*)MEM_callocN(sizeof(DispList), "poly disp"); - dl->nr = totvert; - dl->type = DL_POLY; - dl->parts = 1; - dl->verts = vert = (float*)MEM_callocN(totvert * 3 * sizeof(float), "poly verts"); - dl->index = (int*)MEM_callocN(sizeof(int) * 3 * totvert, "dl index"); - - BLI_addtail(&dispbase, dl); - - for (i = 0; i < totvert; i++) { - copy_v3_v3(vert, verts[indices[i]].co); - vert += 3; - } - - filldisplist(&dispbase, &dispbase, 0); - - int tottri = 0; - dl= (DispList*)dispbase.first; - - if (dl->type == DL_INDEX3) { - tottri = dl->parts; - - int *index = dl->index; - for (i= 0; i < tottri; i++) { - int t[3]= {*index, *(index + 1), *(index + 2)}; - - std::sort(t, t + 3); - - tri.push_back(t[0]); - tri.push_back(t[1]); - tri.push_back(t[2]); - - index += 3; - } - } - - freedisplist(&dispbase); - - return tottri; - } - - int count_new_tris(COLLADAFW::Mesh *mesh, Mesh *me) - { - COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives(); - unsigned int i; - int tottri = 0; - - for (i = 0; i < prim_arr.getCount(); i++) { - - COLLADAFW::MeshPrimitive *mp = prim_arr[i]; - int type = mp->getPrimitiveType(); - size_t prim_totface = mp->getFaceCount(); - unsigned int *indices = mp->getPositionIndices().getData(); - - if (type == COLLADAFW::MeshPrimitive::POLYLIST || - type == COLLADAFW::MeshPrimitive::POLYGONS) { - - COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons*)mp; - COLLADAFW::Polygons::VertexCountArray& vcounta = mpvc->getGroupedVerticesVertexCountArray(); - - for (unsigned int j = 0; j < prim_totface; j++) { - int vcount = vcounta[j]; - - if (vcount > 4) { - std::vector tri; - - // tottri += triangulate_poly(indices, vcount, me->mvert, tri) - 1; // XXX why - 1?! - tottri += triangulate_poly(indices, vcount, me->mvert, tri); - } - - indices += vcount; - } - } - } - return tottri; - } - - // TODO: import uv set names - void read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris) - { - unsigned int i; - - // allocate faces - me->totface = mesh->getFacesCount() + new_tris; - me->mface = (MFace*)CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface); - - // allocate UV layers - unsigned int totuvset = mesh->getUVCoords().getInputInfosArray().getCount(); - - for (i = 0; i < totuvset; i++) { - if (mesh->getUVCoords().getLength(i) == 0) { - totuvset = 0; - break; - } - } - - for (i = 0; i < totuvset; i++) { - COLLADAFW::MeshVertexData::InputInfos *info = mesh->getUVCoords().getInputInfosArray()[i]; - CustomData_add_layer_named(&me->fdata, CD_MTFACE, CD_CALLOC, NULL, me->totface, info->mName.c_str()); - //this->set_layername_map[i] = CustomData_get_layer_name(&me->fdata, CD_MTFACE, i); - } - - // activate the first uv layer - if (totuvset) me->mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, 0); - - UVDataWrapper uvs(mesh->getUVCoords()); - -#ifdef COLLADA_DEBUG - // uvs.print(); -#endif - - MFace *mface = me->mface; - - MaterialIdPrimitiveArrayMap mat_prim_map; - - int face_index = 0; - - COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives(); - - bool has_normals = mesh->hasNormals(); - COLLADAFW::MeshVertexData& nor = mesh->getNormals(); - - for (i = 0; i < prim_arr.getCount(); i++) { - - COLLADAFW::MeshPrimitive *mp = prim_arr[i]; - - // faces - size_t prim_totface = mp->getFaceCount(); - unsigned int *indices = mp->getPositionIndices().getData(); - unsigned int *nind = mp->getNormalIndices().getData(); - unsigned int j, k; - int type = mp->getPrimitiveType(); - int index = 0; - - // since we cannot set mface->mat_nr here, we store a portion of me->mface in Primitive - Primitive prim = {mface, 0}; - COLLADAFW::IndexListArray& index_list_array = mp->getUVCoordIndicesArray(); - -#ifdef COLLADA_DEBUG - /* - fprintf(stderr, "Primitive %d:\n", i); - for (int j = 0; j < totuvset; j++) { - print_index_list(*index_list_array[j]); - } - */ -#endif - - if (type == COLLADAFW::MeshPrimitive::TRIANGLES) { - for (j = 0; j < prim_totface; j++){ - - set_face_indices(mface, indices, false); - indices += 3; - -#if 0 - for (k = 0; k < totuvset; k++) { - if (!index_list_array.empty() && index_list_array[k]) { - // get mtface by face index and uv set index - MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k); - set_face_uv(&mtface[face_index], uvs, k, *index_list_array[k], index, false); - } - } -#else - for (k = 0; k < index_list_array.getCount(); k++) { - int uvset_index = index_list_array[k]->getSetIndex(); - - // get mtface by face index and uv set index - MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, uvset_index); - set_face_uv(&mtface[face_index], uvs, *index_list_array[k], index, false); - } -#endif - - test_index_face(mface, &me->fdata, face_index, 3); - - if (has_normals) { - if (!flat_face(nind, nor, 3)) - mface->flag |= ME_SMOOTH; - - nind += 3; - } - - index += 3; - mface++; - face_index++; - prim.totface++; - } - } - else if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) { - COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons*)mp; - COLLADAFW::Polygons::VertexCountArray& vcounta = mpvc->getGroupedVerticesVertexCountArray(); - - for (j = 0; j < prim_totface; j++) { - - // face - int vcount = vcounta[j]; - if (vcount == 3 || vcount == 4) { - - set_face_indices(mface, indices, vcount == 4); - - // set mtface for each uv set - // it is assumed that all primitives have equal number of UV sets - -#if 0 - for (k = 0; k < totuvset; k++) { - if (!index_list_array.empty() && index_list_array[k]) { - // get mtface by face index and uv set index - MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k); - set_face_uv(&mtface[face_index], uvs, k, *index_list_array[k], index, mface->v4 != 0); - } - } -#else - for (k = 0; k < index_list_array.getCount(); k++) { - int uvset_index = index_list_array[k]->getSetIndex(); - - // get mtface by face index and uv set index - MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, uvset_index); - set_face_uv(&mtface[face_index], uvs, *index_list_array[k], index, mface->v4 != 0); - } -#endif - - test_index_face(mface, &me->fdata, face_index, vcount); - - if (has_normals) { - if (!flat_face(nind, nor, vcount)) - mface->flag |= ME_SMOOTH; - - nind += vcount; - } - - mface++; - face_index++; - prim.totface++; - - } - else { - std::vector tri; - - triangulate_poly(indices, vcount, me->mvert, tri); - - for (k = 0; k < tri.size() / 3; k++) { - int v = k * 3; - unsigned int uv_indices[3] = { - index + tri[v], - index + tri[v + 1], - index + tri[v + 2] - }; - unsigned int tri_indices[3] = { - indices[tri[v]], - indices[tri[v + 1]], - indices[tri[v + 2]] - }; - - set_face_indices(mface, tri_indices, false); - -#if 0 - for (unsigned int l = 0; l < totuvset; l++) { - if (!index_list_array.empty() && index_list_array[l]) { - // get mtface by face index and uv set index - MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, l); - set_face_uv(&mtface[face_index], uvs, l, *index_list_array[l], uv_indices); - } - } -#else - for (unsigned int l = 0; l < index_list_array.getCount(); l++) { - int uvset_index = index_list_array[l]->getSetIndex(); - - // get mtface by face index and uv set index - MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, uvset_index); - set_face_uv(&mtface[face_index], uvs, *index_list_array[l], uv_indices); - } -#endif - - - test_index_face(mface, &me->fdata, face_index, 3); - - if (has_normals) { - unsigned int ntri[3] = {nind[tri[v]], nind[tri[v + 1]], nind[tri[v + 2]]}; - - if (!flat_face(ntri, nor, 3)) - mface->flag |= ME_SMOOTH; - } - - mface++; - face_index++; - prim.totface++; - } - - if (has_normals) - nind += vcount; - } - - index += vcount; - indices += vcount; - } - } - - mat_prim_map[mp->getMaterialId()].push_back(prim); - } - - geom_uid_mat_mapping_map[mesh->getUniqueId()] = mat_prim_map; - } - - void get_vector(float v[3], COLLADAFW::MeshVertexData& arr, int i) - { - i *= 3; - - switch(arr.getType()) { - case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: - { - COLLADAFW::ArrayPrimitiveType* values = arr.getFloatValues(); - if (values->empty()) return; - - v[0] = (*values)[i++]; - v[1] = (*values)[i++]; - v[2] = (*values)[i]; - } - break; - case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE: - { - COLLADAFW::ArrayPrimitiveType* values = arr.getDoubleValues(); - if (values->empty()) return; - - v[0] = (float)(*values)[i++]; - v[1] = (float)(*values)[i++]; - v[2] = (float)(*values)[i]; - } - break; - default: - break; - } - } - - bool flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& nor, int count) - { - float a[3], b[3]; - - get_vector(a, nor, *nind); - normalize_v3(a); - - nind++; - - for (int i = 1; i < count; i++, nind++) { - get_vector(b, nor, *nind); - normalize_v3(b); - - float dp = dot_v3v3(a, b); - - if (dp < 0.99999f || dp > 1.00001f) - return false; - } - - return true; - } - -public: - - MeshImporter(ArmatureImporter *arm, Scene *sce) : scene(sce), armature_importer(arm) {} - - virtual Object *get_object_by_geom_uid(const COLLADAFW::UniqueId& geom_uid) - { - if (uid_object_map.find(geom_uid) != uid_object_map.end()) - return uid_object_map[geom_uid]; - return NULL; - } - - MTex *assign_textures_to_uvlayer(COLLADAFW::TextureCoordinateBinding &ctexture, - Mesh *me, TexIndexTextureArrayMap& texindex_texarray_map, - MTex *color_texture) - { - const COLLADAFW::TextureMapId texture_index = ctexture.getTextureMapId(); - const size_t setindex = ctexture.getSetIndex(); - std::string uvname = ctexture.getName(); - - const CustomData *data = &me->fdata; - int layer_index = CustomData_get_layer_index(data, CD_MTFACE); - CustomDataLayer *cdl = &data->layers[layer_index+setindex]; - - /* set uvname to bind_vertex_input semantic */ - BLI_strncpy(cdl->name, uvname.c_str(), sizeof(cdl->name)); - - if (texindex_texarray_map.find(texture_index) == texindex_texarray_map.end()) { - - fprintf(stderr, "Cannot find texture array by texture index.\n"); - return color_texture; - } - - std::vector textures = texindex_texarray_map[texture_index]; - - std::vector::iterator it; - - for (it = textures.begin(); it != textures.end(); it++) { - - MTex *texture = *it; - - if (texture) { - BLI_strncpy(texture->uvname, uvname.c_str(), sizeof(texture->uvname)); - if (texture->mapto == MAP_COL) color_texture = texture; - } - } - return color_texture; - } - - MTFace *assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial, - std::map& uid_material_map, - Object *ob, const COLLADAFW::UniqueId *geom_uid, - MTex **color_texture, char *layername, MTFace *texture_face, - std::map& material_texture_mapping_map, int mat_index) - { - Mesh *me = (Mesh*)ob->data; - const COLLADAFW::UniqueId& ma_uid = cmaterial.getReferencedMaterial(); - - // do we know this material? - if (uid_material_map.find(ma_uid) == uid_material_map.end()) { - - fprintf(stderr, "Cannot find material by UID.\n"); - return NULL; - } - - Material *ma = uid_material_map[ma_uid]; - assign_material(ob, ma, ob->totcol + 1); - - COLLADAFW::TextureCoordinateBindingArray& tex_array = - cmaterial.getTextureCoordinateBindingArray(); - TexIndexTextureArrayMap texindex_texarray_map = material_texture_mapping_map[ma]; - unsigned int i; - // loop through - for (i = 0; i < tex_array.getCount(); i++) { - - *color_texture = assign_textures_to_uvlayer(tex_array[i], me, texindex_texarray_map, - *color_texture); - } - - // set texture face - if (*color_texture && - strlen((*color_texture)->uvname) && - strcmp(layername, (*color_texture)->uvname) != 0) { - - texture_face = (MTFace*)CustomData_get_layer_named(&me->fdata, CD_MTFACE, - (*color_texture)->uvname); - strcpy(layername, (*color_texture)->uvname); - } - - MaterialIdPrimitiveArrayMap& mat_prim_map = geom_uid_mat_mapping_map[*geom_uid]; - COLLADAFW::MaterialId mat_id = cmaterial.getMaterialId(); - - // assign material indices to mesh faces - if (mat_prim_map.find(mat_id) != mat_prim_map.end()) { - - std::vector& prims = mat_prim_map[mat_id]; - - std::vector::iterator it; - - for (it = prims.begin(); it != prims.end(); it++) { - Primitive& prim = *it; - i = 0; - while (i++ < prim.totface) { - prim.mface->mat_nr = mat_index; - prim.mface++; - // bind texture images to faces - if (texture_face && (*color_texture)) { - texture_face->mode = TF_TEX; - texture_face->tpage = (Image*)(*color_texture)->tex->ima; - texture_face++; - } - } - } - } - - return texture_face; - } - - - Object *create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom, - bool isController, - std::map& uid_material_map, - std::map& material_texture_mapping_map) - { - const COLLADAFW::UniqueId *geom_uid = &geom->getInstanciatedObjectId(); - - // check if node instanciates controller or geometry - if (isController) { - - geom_uid = armature_importer->get_geometry_uid(*geom_uid); - - if (!geom_uid) { - fprintf(stderr, "Couldn't find a mesh UID by controller's UID.\n"); - return NULL; - } - } - else { - - if (uid_mesh_map.find(*geom_uid) == uid_mesh_map.end()) { - // this could happen if a mesh was not created - // (e.g. if it contains unsupported geometry) - fprintf(stderr, "Couldn't find a mesh by UID.\n"); - return NULL; - } - } - if (!uid_mesh_map[*geom_uid]) return NULL; - - Object *ob = add_object(scene, OB_MESH); - - // store object pointer for ArmatureImporter - uid_object_map[*geom_uid] = ob; - - // name Object - const std::string& id = node->getOriginalId(); - if (id.length()) - rename_id(&ob->id, (char*)id.c_str()); - - // replace ob->data freeing the old one - Mesh *old_mesh = (Mesh*)ob->data; - - set_mesh(ob, uid_mesh_map[*geom_uid]); - - if (old_mesh->id.us == 0) free_libblock(&G.main->mesh, old_mesh); - - char layername[100]; - MTFace *texture_face = NULL; - MTex *color_texture = NULL; - - COLLADAFW::MaterialBindingArray& mat_array = - geom->getMaterialBindings(); - - // loop through geom's materials - for (unsigned int i = 0; i < mat_array.getCount(); i++) { - - texture_face = assign_material_to_geom(mat_array[i], uid_material_map, ob, geom_uid, - &color_texture, layername, texture_face, - material_texture_mapping_map, i); - } - - return ob; - } - - // create a mesh storing a pointer in a map so it can be retrieved later by geometry UID - bool write_geometry(const COLLADAFW::Geometry* geom) - { - // TODO: import also uvs, normals - // XXX what to do with normal indices? - // XXX num_normals may be != num verts, then what to do? - - // check geometry->getType() first - if (geom->getType() != COLLADAFW::Geometry::GEO_TYPE_MESH) { - // TODO: report warning - fprintf(stderr, "Mesh type %s is not supported\n", geomTypeToStr(geom->getType())); - return true; - } - - COLLADAFW::Mesh *mesh = (COLLADAFW::Mesh*)geom; - - if (!is_nice_mesh(mesh)) { - fprintf(stderr, "Ignoring mesh %s\n", get_dae_name(mesh)); - return true; - } - - const std::string& str_geom_id = mesh->getOriginalId(); - Mesh *me = add_mesh((char*)str_geom_id.c_str()); - - // store the Mesh pointer to link it later with an Object - this->uid_mesh_map[mesh->getUniqueId()] = me; - - int new_tris = 0; - - read_vertices(mesh, me); - - new_tris = count_new_tris(mesh, me); - - read_faces(mesh, me, new_tris); - - make_edges(me, 0); - - mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); - - return true; - } - -}; - -class AnimationImporter : private TransformReader, public AnimationImporterBase -{ -private: - - ArmatureImporter *armature_importer; - Scene *scene; - - std::map > curve_map; - std::map uid_animated_map; - // std::map > fcurves_actionGroup_map; - std::map animlist_map; - std::vector unused_curves; - std::map joint_objects; - - FCurve *create_fcurve(int array_index, const char *rna_path) - { - FCurve *fcu = (FCurve*)MEM_callocN(sizeof(FCurve), "FCurve"); - - fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED); - fcu->rna_path = BLI_strdupn(rna_path, strlen(rna_path)); - fcu->array_index = array_index; - return fcu; - } - - void create_bezt(FCurve *fcu, float frame, float output) - { - BezTriple bez; - memset(&bez, 0, sizeof(BezTriple)); - bez.vec[1][0] = frame; - bez.vec[1][1] = output; - bez.ipo = U.ipo_new; /* use default interpolation mode here... */ - bez.f1 = bez.f2 = bez.f3 = SELECT; - bez.h1 = bez.h2 = HD_AUTO; - insert_bezt_fcurve(fcu, &bez, 0); - calchandles_fcurve(fcu); - } - - // create one or several fcurves depending on the number of parameters being animated - void animation_to_fcurves(COLLADAFW::AnimationCurve *curve) - { - COLLADAFW::FloatOrDoubleArray& input = curve->getInputValues(); - COLLADAFW::FloatOrDoubleArray& output = curve->getOutputValues(); - // COLLADAFW::FloatOrDoubleArray& intan = curve->getInTangentValues(); - // COLLADAFW::FloatOrDoubleArray& outtan = curve->getOutTangentValues(); - float fps = (float)FPS; - size_t dim = curve->getOutDimension(); - unsigned int i; - - std::vector& fcurves = curve_map[curve->getUniqueId()]; - - switch (dim) { - case 1: // X, Y, Z or angle - case 3: // XYZ - case 16: // matrix - { - for (i = 0; i < dim; i++ ) { - FCurve *fcu = (FCurve*)MEM_callocN(sizeof(FCurve), "FCurve"); - - fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED); - // fcu->rna_path = BLI_strdupn(path, strlen(path)); - fcu->array_index = 0; - //fcu->totvert = curve->getKeyCount(); - - // create beztriple for each key - for (unsigned int j = 0; j < curve->getKeyCount(); j++) { - BezTriple bez; - memset(&bez, 0, sizeof(BezTriple)); - - // intangent - // bez.vec[0][0] = get_float_value(intan, j * 6 + i + i) * fps; - // bez.vec[0][1] = get_float_value(intan, j * 6 + i + i + 1); - - // input, output - bez.vec[1][0] = get_float_value(input, j) * fps; - bez.vec[1][1] = get_float_value(output, j * dim + i); - - // outtangent - // bez.vec[2][0] = get_float_value(outtan, j * 6 + i + i) * fps; - // bez.vec[2][1] = get_float_value(outtan, j * 6 + i + i + 1); - - bez.ipo = U.ipo_new; /* use default interpolation mode here... */ - bez.f1 = bez.f2 = bez.f3 = SELECT; - bez.h1 = bez.h2 = HD_AUTO; - insert_bezt_fcurve(fcu, &bez, 0); - } - - calchandles_fcurve(fcu); - - fcurves.push_back(fcu); - } - } - break; - default: - fprintf(stderr, "Output dimension of %d is not yet supported (animation id = %s)\n", dim, curve->getOriginalId().c_str()); - } - - for (std::vector::iterator it = fcurves.begin(); it != fcurves.end(); it++) - unused_curves.push_back(*it); - } - - void fcurve_deg_to_rad(FCurve *cu) - { - for (unsigned int i = 0; i < cu->totvert; i++) { - // TODO convert handles too - cu->bezt[i].vec[1][1] *= M_PI / 180.0f; - } - } - - void add_fcurves_to_object(Object *ob, std::vector& curves, char *rna_path, int array_index, Animation *animated) - { - bAction *act; - - if (!ob->adt || !ob->adt->action) act = verify_adt_action((ID*)&ob->id, 1); - else act = ob->adt->action; - - std::vector::iterator it; - int i; - -#if 0 - char *p = strstr(rna_path, "rotation_euler"); - bool is_rotation = p && *(p + strlen("rotation_euler")) == '\0'; - - // convert degrees to radians for rotation - if (is_rotation) - fcurve_deg_to_rad(fcu); -#endif - - for (it = curves.begin(), i = 0; it != curves.end(); it++, i++) { - FCurve *fcu = *it; - fcu->rna_path = BLI_strdupn(rna_path, strlen(rna_path)); - - if (array_index == -1) fcu->array_index = i; - else fcu->array_index = array_index; - - if (ob->type == OB_ARMATURE) { - bActionGroup *grp = NULL; - const char *bone_name = get_joint_name(animated->node); - - if (bone_name) { - /* try to find group */ - grp = action_groups_find_named(act, bone_name); - - /* no matching groups, so add one */ - if (grp == NULL) { - /* Add a new group, and make it active */ - grp = (bActionGroup*)MEM_callocN(sizeof(bActionGroup), "bActionGroup"); - - grp->flag = AGRP_SELECTED; - BLI_strncpy(grp->name, bone_name, sizeof(grp->name)); - - BLI_addtail(&act->groups, grp); - BLI_uniquename(&act->groups, grp, "Group", '.', offsetof(bActionGroup, name), 64); - } - - /* add F-Curve to group */ - action_groups_add_channel(act, grp, fcu); - - } -#if 0 - if (is_rotation) { - fcurves_actionGroup_map[grp].push_back(fcu); - } -#endif - } - else { - BLI_addtail(&act->curves, fcu); - } - - // curve is used, so remove it from unused_curves - unused_curves.erase(std::remove(unused_curves.begin(), unused_curves.end(), fcu), unused_curves.end()); - } - } -public: - - AnimationImporter(UnitConverter *conv, ArmatureImporter *arm, Scene *scene) : - TransformReader(conv), armature_importer(arm), scene(scene) { } - - ~AnimationImporter() - { - // free unused FCurves - for (std::vector::iterator it = unused_curves.begin(); it != unused_curves.end(); it++) - free_fcurve(*it); - - if (unused_curves.size()) - fprintf(stderr, "removed %u unused curves\n", unused_curves.size()); - } - - bool write_animation(const COLLADAFW::Animation* anim) - { - if (anim->getAnimationType() == COLLADAFW::Animation::ANIMATION_CURVE) { - COLLADAFW::AnimationCurve *curve = (COLLADAFW::AnimationCurve*)anim; - - // XXX Don't know if it's necessary - // Should we check outPhysicalDimension? - if (curve->getInPhysicalDimension() != COLLADAFW::PHYSICAL_DIMENSION_TIME) { - fprintf(stderr, "Inputs physical dimension is not time. \n"); - return true; - } - - // a curve can have mixed interpolation type, - // in this case curve->getInterpolationTypes returns a list of interpolation types per key - COLLADAFW::AnimationCurve::InterpolationType interp = curve->getInterpolationType(); - - if (interp != COLLADAFW::AnimationCurve::INTERPOLATION_MIXED) { - switch (interp) { - case COLLADAFW::AnimationCurve::INTERPOLATION_LINEAR: - case COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER: - animation_to_fcurves(curve); - break; - default: - // TODO there're also CARDINAL, HERMITE, BSPLINE and STEP types - fprintf(stderr, "CARDINAL, HERMITE, BSPLINE and STEP anim interpolation types not supported yet.\n"); - break; - } - } - else { - // not supported yet - fprintf(stderr, "MIXED anim interpolation type is not supported yet.\n"); - } - } - else { - fprintf(stderr, "FORMULA animation type is not supported yet.\n"); - } - - return true; - } - - // called on post-process stage after writeVisualScenes - bool write_animation_list(const COLLADAFW::AnimationList* animlist) - { - const COLLADAFW::UniqueId& animlist_id = animlist->getUniqueId(); - - animlist_map[animlist_id] = animlist; - -#if 0 - // should not happen - if (uid_animated_map.find(animlist_id) == uid_animated_map.end()) { - return true; - } - - // for bones rna_path is like: pose.bones["bone-name"].rotation - - // what does this AnimationList animate? - Animation& animated = uid_animated_map[animlist_id]; - Object *ob = animated.ob; - - char rna_path[100]; - char joint_path[100]; - bool is_joint = false; - - // if ob is NULL, it should be a JOINT - if (!ob) { - ob = armature_importer->get_armature_for_joint(animated.node); - - if (!ob) { - fprintf(stderr, "Cannot find armature for node %s\n", get_joint_name(animated.node)); - return true; - } - - armature_importer->get_rna_path_for_joint(animated.node, joint_path, sizeof(joint_path)); - - is_joint = true; - } - - const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings(); - - switch (animated.tm->getTransformationType()) { - case COLLADAFW::Transformation::TRANSLATE: - case COLLADAFW::Transformation::SCALE: - { - bool loc = animated.tm->getTransformationType() == COLLADAFW::Transformation::TRANSLATE; - if (is_joint) - BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, loc ? "location" : "scale"); - else - BLI_strncpy(rna_path, loc ? "location" : "scale", sizeof(rna_path)); - - for (int i = 0; i < bindings.getCount(); i++) { - const COLLADAFW::AnimationList::AnimationBinding& binding = bindings[i]; - COLLADAFW::UniqueId anim_uid = binding.animation; - - if (curve_map.find(anim_uid) == curve_map.end()) { - fprintf(stderr, "Cannot find FCurve by animation UID.\n"); - continue; - } - - std::vector& fcurves = curve_map[anim_uid]; - - switch (binding.animationClass) { - case COLLADAFW::AnimationList::POSITION_X: - add_fcurves_to_object(ob, fcurves, rna_path, 0, &animated); - break; - case COLLADAFW::AnimationList::POSITION_Y: - add_fcurves_to_object(ob, fcurves, rna_path, 1, &animated); - break; - case COLLADAFW::AnimationList::POSITION_Z: - add_fcurves_to_object(ob, fcurves, rna_path, 2, &animated); - break; - case COLLADAFW::AnimationList::POSITION_XYZ: - add_fcurves_to_object(ob, fcurves, rna_path, -1, &animated); - break; - default: - fprintf(stderr, "AnimationClass %d is not supported for %s.\n", - binding.animationClass, loc ? "TRANSLATE" : "SCALE"); - } - } - } - break; - case COLLADAFW::Transformation::ROTATE: - { - if (is_joint) - BLI_snprintf(rna_path, sizeof(rna_path), "%s.rotation_euler", joint_path); - else - BLI_strncpy(rna_path, "rotation_euler", sizeof(rna_path)); - - COLLADAFW::Rotate* rot = (COLLADAFW::Rotate*)animated.tm; - COLLADABU::Math::Vector3& axis = rot->getRotationAxis(); - - for (int i = 0; i < bindings.getCount(); i++) { - const COLLADAFW::AnimationList::AnimationBinding& binding = bindings[i]; - COLLADAFW::UniqueId anim_uid = binding.animation; - - if (curve_map.find(anim_uid) == curve_map.end()) { - fprintf(stderr, "Cannot find FCurve by animation UID.\n"); - continue; - } - - std::vector& fcurves = curve_map[anim_uid]; - - switch (binding.animationClass) { - case COLLADAFW::AnimationList::ANGLE: - if (COLLADABU::Math::Vector3::UNIT_X == axis) { - add_fcurves_to_object(ob, fcurves, rna_path, 0, &animated); - } - else if (COLLADABU::Math::Vector3::UNIT_Y == axis) { - add_fcurves_to_object(ob, fcurves, rna_path, 1, &animated); - } - else if (COLLADABU::Math::Vector3::UNIT_Z == axis) { - add_fcurves_to_object(ob, fcurves, rna_path, 2, &animated); - } - break; - case COLLADAFW::AnimationList::AXISANGLE: - // TODO convert axis-angle to quat? or XYZ? - default: - fprintf(stderr, "AnimationClass %d is not supported for ROTATE transformation.\n", - binding.animationClass); - } - } - } - break; - case COLLADAFW::Transformation::MATRIX: - case COLLADAFW::Transformation::SKEW: - case COLLADAFW::Transformation::LOOKAT: - fprintf(stderr, "Animation of MATRIX, SKEW and LOOKAT transformations is not supported yet.\n"); - break; - } -#endif - - return true; - } - - void read_node_transform(COLLADAFW::Node *node, Object *ob) - { - float mat[4][4]; - TransformReader::get_node_mat(mat, node, &uid_animated_map, ob); - if (ob) { - copy_m4_m4(ob->obmat, mat); - object_apply_mat4(ob, ob->obmat); - } - } - -#if 0 - virtual void change_eul_to_quat(Object *ob, bAction *act) - { - bActionGroup *grp; - int i; - - for (grp = (bActionGroup*)act->groups.first; grp; grp = grp->next) { - - FCurve *eulcu[3] = {NULL, NULL, NULL}; - - if (fcurves_actionGroup_map.find(grp) == fcurves_actionGroup_map.end()) - continue; - - std::vector &rot_fcurves = fcurves_actionGroup_map[grp]; - - if (rot_fcurves.size() > 3) continue; - - for (i = 0; i < rot_fcurves.size(); i++) - eulcu[rot_fcurves[i]->array_index] = rot_fcurves[i]; - - char joint_path[100]; - char rna_path[100]; - - BLI_snprintf(joint_path, sizeof(joint_path), "pose.bones[\"%s\"]", grp->name); - BLI_snprintf(rna_path, sizeof(rna_path), "%s.rotation_quaternion", joint_path); - - FCurve *quatcu[4] = { - create_fcurve(0, rna_path), - create_fcurve(1, rna_path), - create_fcurve(2, rna_path), - create_fcurve(3, rna_path) - }; - - bPoseChannel *chan = get_pose_channel(ob->pose, grp->name); - - float m4[4][4], irest[3][3]; - invert_m4_m4(m4, chan->bone->arm_mat); - copy_m3_m4(irest, m4); - - for (i = 0; i < 3; i++) { - - FCurve *cu = eulcu[i]; - - if (!cu) continue; - - for (int j = 0; j < cu->totvert; j++) { - float frame = cu->bezt[j].vec[1][0]; - - float eul[3] = { - eulcu[0] ? evaluate_fcurve(eulcu[0], frame) : 0.0f, - eulcu[1] ? evaluate_fcurve(eulcu[1], frame) : 0.0f, - eulcu[2] ? evaluate_fcurve(eulcu[2], frame) : 0.0f - }; - - // make eul relative to bone rest pose - float rot[3][3], rel[3][3], quat[4]; - - /*eul_to_mat3(rot, eul); - - mul_m3_m3m3(rel, irest, rot); - - mat3_to_quat(quat, rel); - */ - - eul_to_quat(quat, eul); - - for (int k = 0; k < 4; k++) - create_bezt(quatcu[k], frame, quat[k]); - } - } - - // now replace old Euler curves - - for (i = 0; i < 3; i++) { - if (!eulcu[i]) continue; - - action_groups_remove_channel(act, eulcu[i]); - free_fcurve(eulcu[i]); - } - - chan->rotmode = ROT_MODE_QUAT; - - for (i = 0; i < 4; i++) - action_groups_add_channel(act, grp, quatcu[i]); - } - - bPoseChannel *pchan; - for (pchan = (bPoseChannel*)ob->pose->chanbase.first; pchan; pchan = pchan->next) { - pchan->rotmode = ROT_MODE_QUAT; - } - } -#endif - - // prerequisites: - // animlist_map - map animlist id -> animlist - // curve_map - map anim id -> curve(s) - Object *translate_animation(COLLADAFW::Node *node, - std::map& object_map, - std::map& root_map, - COLLADAFW::Transformation::TransformationType tm_type, - Object *par_job = NULL) - { - bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE; - bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX; - bool is_joint = node->getType() == COLLADAFW::Node::JOINT; - - COLLADAFW::Node *root = root_map.find(node->getUniqueId()) == root_map.end() ? node : root_map[node->getUniqueId()]; - Object *ob = is_joint ? armature_importer->get_armature_for_joint(node) : object_map[node->getUniqueId()]; - const char *bone_name = is_joint ? get_joint_name(node) : NULL; - - if (!ob) { - fprintf(stderr, "cannot find Object for Node with id=\"%s\"\n", node->getOriginalId().c_str()); - return NULL; - } - - // frames at which to sample - std::vector frames; - - // for each , , etc. there is a separate Transformation - const COLLADAFW::TransformationPointerArray& tms = node->getTransformations(); - - unsigned int i; - - // find frames at which to sample plus convert all rotation keys to radians - for (i = 0; i < tms.getCount(); i++) { - COLLADAFW::Transformation *tm = tms[i]; - COLLADAFW::Transformation::TransformationType type = tm->getTransformationType(); - - if (type == tm_type) { - const COLLADAFW::UniqueId& listid = tm->getAnimationList(); - - if (animlist_map.find(listid) != animlist_map.end()) { - const COLLADAFW::AnimationList *animlist = animlist_map[listid]; - const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings(); - - if (bindings.getCount()) { - for (unsigned int j = 0; j < bindings.getCount(); j++) { - std::vector& curves = curve_map[bindings[j].animation]; - bool xyz = ((type == COLLADAFW::Transformation::TRANSLATE || type == COLLADAFW::Transformation::SCALE) && bindings[j].animationClass == COLLADAFW::AnimationList::POSITION_XYZ); - - if ((!xyz && curves.size() == 1) || (xyz && curves.size() == 3) || is_matrix) { - std::vector::iterator iter; - - for (iter = curves.begin(); iter != curves.end(); iter++) { - FCurve *fcu = *iter; - - if (is_rotation) - fcurve_deg_to_rad(fcu); - - for (unsigned int k = 0; k < fcu->totvert; k++) { - float fra = fcu->bezt[k].vec[1][0]; - if (std::find(frames.begin(), frames.end(), fra) == frames.end()) - frames.push_back(fra); - } - } - } - else { - fprintf(stderr, "expected %d curves, got %u\n", xyz ? 3 : 1, curves.size()); - } - } - } - } - } - } - - float irest_dae[4][4]; - float rest[4][4], irest[4][4]; - - if (is_joint) { - get_joint_rest_mat(irest_dae, root, node); - invert_m4(irest_dae); - - Bone *bone = get_named_bone((bArmature*)ob->data, bone_name); - if (!bone) { - fprintf(stderr, "cannot find bone \"%s\"\n", bone_name); - return NULL; - } - - unit_m4(rest); - copy_m4_m4(rest, bone->arm_mat); - invert_m4_m4(irest, rest); - } - - Object *job = NULL; - -#ifdef ARMATURE_TEST - FCurve *job_curves[10]; - job = get_joint_object(root, node, par_job); -#endif - - if (frames.size() == 0) - return job; - - std::sort(frames.begin(), frames.end()); - - const char *tm_str = NULL; - switch (tm_type) { - case COLLADAFW::Transformation::ROTATE: - tm_str = "rotation_quaternion"; - break; - case COLLADAFW::Transformation::SCALE: - tm_str = "scale"; - break; - case COLLADAFW::Transformation::TRANSLATE: - tm_str = "location"; - break; - case COLLADAFW::Transformation::MATRIX: - break; - default: - return job; - } - - char rna_path[200]; - char joint_path[200]; - - if (is_joint) - armature_importer->get_rna_path_for_joint(node, joint_path, sizeof(joint_path)); - - // new curves - FCurve *newcu[10]; // if tm_type is matrix, then create 10 curves: 4 rot, 3 loc, 3 scale - unsigned int totcu = is_matrix ? 10 : (is_rotation ? 4 : 3); - - for (i = 0; i < totcu; i++) { - - int axis = i; - - if (is_matrix) { - if (i < 4) { - tm_str = "rotation_quaternion"; - axis = i; - } - else if (i < 7) { - tm_str = "location"; - axis = i - 4; - } - else { - tm_str = "scale"; - axis = i - 7; - } - } - - if (is_joint) - BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, tm_str); - else - strcpy(rna_path, tm_str); - - newcu[i] = create_fcurve(axis, rna_path); - -#ifdef ARMATURE_TEST - if (is_joint) - job_curves[i] = create_fcurve(axis, tm_str); -#endif - } - - std::vector::iterator it; - - // sample values at each frame - for (it = frames.begin(); it != frames.end(); it++) { - float fra = *it; - - float mat[4][4]; - float matfra[4][4]; - - unit_m4(matfra); - - // calc object-space mat - evaluate_transform_at_frame(matfra, node, fra); - - // for joints, we need a special matrix - if (is_joint) { - // special matrix: iR * M * iR_dae * R - // where R, iR are bone rest and inverse rest mats in world space (Blender bones), - // iR_dae is joint inverse rest matrix (DAE) and M is an evaluated joint world-space matrix (DAE) - float temp[4][4], par[4][4]; - - // calc M - calc_joint_parent_mat_rest(par, NULL, root, node); - mul_m4_m4m4(temp, matfra, par); - - // evaluate_joint_world_transform_at_frame(temp, NULL, , node, fra); - - // calc special matrix - mul_serie_m4(mat, irest, temp, irest_dae, rest, NULL, NULL, NULL, NULL); - } - else { - copy_m4_m4(mat, matfra); - } - - float val[4], rot[4], loc[3], scale[3]; - - switch (tm_type) { - case COLLADAFW::Transformation::ROTATE: - mat4_to_quat(val, mat); - break; - case COLLADAFW::Transformation::SCALE: - mat4_to_size(val, mat); - break; - case COLLADAFW::Transformation::TRANSLATE: - copy_v3_v3(val, mat[3]); - break; - case COLLADAFW::Transformation::MATRIX: - mat4_to_quat(rot, mat); - copy_v3_v3(loc, mat[3]); - mat4_to_size(scale, mat); - break; - default: - break; - } - - // add keys - for (i = 0; i < totcu; i++) { - if (is_matrix) { - if (i < 4) - add_bezt(newcu[i], fra, rot[i]); - else if (i < 7) - add_bezt(newcu[i], fra, loc[i - 4]); - else - add_bezt(newcu[i], fra, scale[i - 7]); - } - else { - add_bezt(newcu[i], fra, val[i]); - } - } - -#ifdef ARMATURE_TEST - if (is_joint) { - switch (tm_type) { - case COLLADAFW::Transformation::ROTATE: - mat4_to_quat(val, matfra); - break; - case COLLADAFW::Transformation::SCALE: - mat4_to_size(val, matfra); - break; - case COLLADAFW::Transformation::TRANSLATE: - copy_v3_v3(val, matfra[3]); - break; - case MATRIX: - mat4_to_quat(rot, matfra); - copy_v3_v3(loc, matfra[3]); - mat4_to_size(scale, matfra); - break; - default: - break; - } - - for (i = 0; i < totcu; i++) { - if (is_matrix) { - if (i < 4) - add_bezt(job_curves[i], fra, rot[i]); - else if (i < 7) - add_bezt(job_curves[i], fra, loc[i - 4]); - else - add_bezt(job_curves[i], fra, scale[i - 7]); - } - else { - add_bezt(job_curves[i], fra, val[i]); - } - } - } -#endif - } - - verify_adt_action((ID*)&ob->id, 1); - - ListBase *curves = &ob->adt->action->curves; - - // add curves - for (i = 0; i < totcu; i++) { - if (is_joint) - add_bone_fcurve(ob, node, newcu[i]); - else - BLI_addtail(curves, newcu[i]); - -#ifdef ARMATURE_TEST - if (is_joint) - BLI_addtail(&job->adt->action->curves, job_curves[i]); -#endif - } - - if (is_rotation || is_matrix) { - if (is_joint) { - bPoseChannel *chan = get_pose_channel(ob->pose, bone_name); - chan->rotmode = ROT_MODE_QUAT; - } - else { - ob->rotmode = ROT_MODE_QUAT; - } - } - - return job; - } - - // internal, better make it private - // warning: evaluates only rotation - // prerequisites: animlist_map, curve_map - void evaluate_transform_at_frame(float mat[4][4], COLLADAFW::Node *node, float fra) - { - const COLLADAFW::TransformationPointerArray& tms = node->getTransformations(); - - unit_m4(mat); - - for (unsigned int i = 0; i < tms.getCount(); i++) { - COLLADAFW::Transformation *tm = tms[i]; - COLLADAFW::Transformation::TransformationType type = tm->getTransformationType(); - float m[4][4]; - - unit_m4(m); - - if (!evaluate_animation(tm, m, fra, node->getOriginalId().c_str())) { - switch (type) { - case COLLADAFW::Transformation::ROTATE: - dae_rotate_to_mat4(tm, m); - break; - case COLLADAFW::Transformation::TRANSLATE: - dae_translate_to_mat4(tm, m); - break; - case COLLADAFW::Transformation::SCALE: - dae_scale_to_mat4(tm, m); - break; - case COLLADAFW::Transformation::MATRIX: - dae_matrix_to_mat4(tm, m); - break; - default: - fprintf(stderr, "unsupported transformation type %d\n", type); - } - } - - float temp[4][4]; - copy_m4_m4(temp, mat); - - mul_m4_m4m4(mat, m, temp); - } - } - - // return true to indicate that mat contains a sane value - bool evaluate_animation(COLLADAFW::Transformation *tm, float mat[4][4], float fra, const char *node_id) - { - const COLLADAFW::UniqueId& listid = tm->getAnimationList(); - COLLADAFW::Transformation::TransformationType type = tm->getTransformationType(); - - if (type != COLLADAFW::Transformation::ROTATE && - type != COLLADAFW::Transformation::SCALE && - type != COLLADAFW::Transformation::TRANSLATE && - type != COLLADAFW::Transformation::MATRIX) { - fprintf(stderr, "animation of transformation %d is not supported yet\n", type); - return false; - } - - if (animlist_map.find(listid) == animlist_map.end()) - return false; - - const COLLADAFW::AnimationList *animlist = animlist_map[listid]; - const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings(); - - if (bindings.getCount()) { - float vec[3]; - - bool is_scale = (type == COLLADAFW::Transformation::SCALE); - bool is_translate = (type == COLLADAFW::Transformation::TRANSLATE); - - if (type == COLLADAFW::Transformation::SCALE) - dae_scale_to_v3(tm, vec); - else if (type == COLLADAFW::Transformation::TRANSLATE) - dae_translate_to_v3(tm, vec); - - for (unsigned int j = 0; j < bindings.getCount(); j++) { - const COLLADAFW::AnimationList::AnimationBinding& binding = bindings[j]; - std::vector& curves = curve_map[binding.animation]; - COLLADAFW::AnimationList::AnimationClass animclass = binding.animationClass; - char path[100]; - - switch (type) { - case COLLADAFW::Transformation::ROTATE: - BLI_snprintf(path, sizeof(path), "%s.rotate (binding %u)", node_id, j); - break; - case COLLADAFW::Transformation::SCALE: - BLI_snprintf(path, sizeof(path), "%s.scale (binding %u)", node_id, j); - break; - case COLLADAFW::Transformation::TRANSLATE: - BLI_snprintf(path, sizeof(path), "%s.translate (binding %u)", node_id, j); - break; - case COLLADAFW::Transformation::MATRIX: - BLI_snprintf(path, sizeof(path), "%s.matrix (binding %u)", node_id, j); - break; - default: - break; - } - - if (animclass == COLLADAFW::AnimationList::UNKNOWN_CLASS) { - fprintf(stderr, "%s: UNKNOWN animation class\n", path); - continue; - } - - if (type == COLLADAFW::Transformation::ROTATE) { - if (curves.size() != 1) { - fprintf(stderr, "expected 1 curve, got %u\n", curves.size()); - return false; - } - - // TODO support other animclasses - if (animclass != COLLADAFW::AnimationList::ANGLE) { - fprintf(stderr, "%s: animation class %d is not supported yet\n", path, animclass); - return false; - } - - COLLADABU::Math::Vector3& axis = ((COLLADAFW::Rotate*)tm)->getRotationAxis(); - float ax[3] = {axis[0], axis[1], axis[2]}; - float angle = evaluate_fcurve(curves[0], fra); - axis_angle_to_mat4(mat, ax, angle); - - return true; - } - else if (is_scale || is_translate) { - bool is_xyz = animclass == COLLADAFW::AnimationList::POSITION_XYZ; - - if ((!is_xyz && curves.size() != 1) || (is_xyz && curves.size() != 3)) { - if (is_xyz) - fprintf(stderr, "%s: expected 3 curves, got %u\n", path, curves.size()); - else - fprintf(stderr, "%s: expected 1 curve, got %u\n", path, curves.size()); - return false; - } - - switch (animclass) { - case COLLADAFW::AnimationList::POSITION_X: - vec[0] = evaluate_fcurve(curves[0], fra); - break; - case COLLADAFW::AnimationList::POSITION_Y: - vec[1] = evaluate_fcurve(curves[0], fra); - break; - case COLLADAFW::AnimationList::POSITION_Z: - vec[2] = evaluate_fcurve(curves[0], fra); - break; - case COLLADAFW::AnimationList::POSITION_XYZ: - vec[0] = evaluate_fcurve(curves[0], fra); - vec[1] = evaluate_fcurve(curves[1], fra); - vec[2] = evaluate_fcurve(curves[2], fra); - break; - default: - fprintf(stderr, "%s: animation class %d is not supported yet\n", path, animclass); - break; - } - } - else if (type == COLLADAFW::Transformation::MATRIX) { - // for now, of matrix animation, support only the case when all values are packed into one animation - if (curves.size() != 16) { - fprintf(stderr, "%s: expected 16 curves, got %u\n", path, curves.size()); - return false; - } - - COLLADABU::Math::Matrix4 matrix; - int i = 0, j = 0; - - for (std::vector::iterator it = curves.begin(); it != curves.end(); it++) { - matrix.setElement(i, j, evaluate_fcurve(*it, fra)); - j++; - if (j == 4) { - i++; - j = 0; - } - } - - COLLADAFW::Matrix tm(matrix); - dae_matrix_to_mat4(&tm, mat); - - return true; - } - } - - if (is_scale) - size_to_mat4(mat, vec); - else - copy_v3_v3(mat[3], vec); - - return is_scale || is_translate; - } - - return false; - } - - // gives a world-space mat of joint at rest position - void get_joint_rest_mat(float mat[4][4], COLLADAFW::Node *root, COLLADAFW::Node *node) - { - // if bind mat is not available, - // use "current" node transform, i.e. all those tms listed inside - if (!armature_importer->get_joint_bind_mat(mat, node)) { - float par[4][4], m[4][4]; - - calc_joint_parent_mat_rest(par, NULL, root, node); - get_node_mat(m, node, NULL, NULL); - mul_m4_m4m4(mat, m, par); - } - } - - // gives a world-space mat, end's mat not included - bool calc_joint_parent_mat_rest(float mat[4][4], float par[4][4], COLLADAFW::Node *node, COLLADAFW::Node *end) - { - float m[4][4]; - - if (node == end) { - par ? copy_m4_m4(mat, par) : unit_m4(mat); - return true; - } - - // use bind matrix if available or calc "current" world mat - if (!armature_importer->get_joint_bind_mat(m, node)) { - if (par) { - float temp[4][4]; - get_node_mat(temp, node, NULL, NULL); - mul_m4_m4m4(m, temp, par); - } - else { - get_node_mat(m, node, NULL, NULL); - } - } - - COLLADAFW::NodePointerArray& children = node->getChildNodes(); - for (unsigned int i = 0; i < children.getCount(); i++) { - if (calc_joint_parent_mat_rest(mat, m, children[i], end)) - return true; - } - - return false; - } - -#ifdef ARMATURE_TEST - Object *get_joint_object(COLLADAFW::Node *root, COLLADAFW::Node *node, Object *par_job) - { - if (joint_objects.find(node->getUniqueId()) == joint_objects.end()) { - Object *job = add_object(scene, OB_EMPTY); - - rename_id((ID*)&job->id, (char*)get_joint_name(node)); - - job->lay = object_in_scene(job, scene)->lay = 2; - - mul_v3_fl(job->size, 0.5f); - job->recalc |= OB_RECALC_OB; - - verify_adt_action((ID*)&job->id, 1); - - job->rotmode = ROT_MODE_QUAT; - - float mat[4][4]; - get_joint_rest_mat(mat, root, node); - - if (par_job) { - float temp[4][4], ipar[4][4]; - invert_m4_m4(ipar, par_job->obmat); - copy_m4_m4(temp, mat); - mul_m4_m4m4(mat, temp, ipar); - } - - TransformBase::decompose(mat, job->loc, NULL, job->quat, job->size); - - if (par_job) { - job->parent = par_job; - - par_job->recalc |= OB_RECALC_OB; - job->parsubstr[0] = 0; - } - - where_is_object(scene, job); - - // after parenting and layer change - DAG_scene_sort(CTX_data_main(C), scene); - - joint_objects[node->getUniqueId()] = job; - } - - return joint_objects[node->getUniqueId()]; - } -#endif - -#if 0 - // recursively evaluates joint tree until end is found, mat then is world-space matrix of end - // mat must be identity on enter, node must be root - bool evaluate_joint_world_transform_at_frame(float mat[4][4], float par[4][4], COLLADAFW::Node *node, COLLADAFW::Node *end, float fra) - { - float m[4][4]; - if (par) { - float temp[4][4]; - evaluate_transform_at_frame(temp, node, node == end ? fra : 0.0f); - mul_m4_m4m4(m, temp, par); - } - else { - evaluate_transform_at_frame(m, node, node == end ? fra : 0.0f); - } - - if (node == end) { - copy_m4_m4(mat, m); - return true; - } - else { - COLLADAFW::NodePointerArray& children = node->getChildNodes(); - for (int i = 0; i < children.getCount(); i++) { - if (evaluate_joint_world_transform_at_frame(mat, m, children[i], end, fra)) - return true; - } - } - - return false; - } -#endif - - void add_bone_fcurve(Object *ob, COLLADAFW::Node *node, FCurve *fcu) - { - const char *bone_name = get_joint_name(node); - bAction *act = ob->adt->action; - - /* try to find group */ - bActionGroup *grp = action_groups_find_named(act, bone_name); - - /* no matching groups, so add one */ - if (grp == NULL) { - /* Add a new group, and make it active */ - grp = (bActionGroup*)MEM_callocN(sizeof(bActionGroup), "bActionGroup"); - - grp->flag = AGRP_SELECTED; - BLI_strncpy(grp->name, bone_name, sizeof(grp->name)); - - BLI_addtail(&act->groups, grp); - BLI_uniquename(&act->groups, grp, "Group", '.', offsetof(bActionGroup, name), 64); - } - - /* add F-Curve to group */ - action_groups_add_channel(act, grp, fcu); - } - - void add_bezt(FCurve *fcu, float fra, float value) - { - BezTriple bez; - memset(&bez, 0, sizeof(BezTriple)); - bez.vec[1][0] = fra; - bez.vec[1][1] = value; - bez.ipo = U.ipo_new; /* use default interpolation mode here... */ - bez.f1 = bez.f2 = bez.f3 = SELECT; - bez.h1 = bez.h2 = HD_AUTO; - insert_bezt_fcurve(fcu, &bez, 0); - calchandles_fcurve(fcu); - } -}; - -/* - - COLLADA Importer limitations: - - - no multiple scene import, all objects are added to active scene - - */ /** Class that needs to be implemented by a writer. IMPORTANT: The write functions are called in arbitrary order.*/ class Writer: public COLLADAFW::IWriter @@ -3468,7 +332,7 @@ public: else { new_child = create_instance_node(object_map[child_id], child_node, NULL, sce, is_library_node); } - set_parent(new_child, obn, mContext, true); + bc_set_parent(new_child, obn, mContext, true); if (is_library_node) libnode_ob.push_back(new_child); @@ -3547,7 +411,7 @@ public: if (!is_joint) { // if par was given make this object child of the previous if (par && ob) - set_parent(ob, par, mContext); + bc_set_parent(ob, par, mContext); } // if node has child nodes write them @@ -3650,8 +514,7 @@ public: // phong else if (shader == COLLADAFW::EffectCommon::SHADER_PHONG) { ma->spec_shader = MA_SPEC_PHONG; - // XXX setting specular hardness instead of specularity intensity - ma->har = ef->getShininess().getFloatValue() * 4; + ma->har = ef->getShininess().getFloatValue(); } // lambert else if (shader == COLLADAFW::EffectCommon::SHADER_LAMBERT) { diff --git a/source/blender/collada/DocumentImporter.h b/source/blender/collada/DocumentImporter.h index babf8f65d7f..6a6f1dcb3bc 100644 --- a/source/blender/collada/DocumentImporter.h +++ b/source/blender/collada/DocumentImporter.h @@ -21,6 +21,9 @@ * * ***** END GPL LICENSE BLOCK ***** */ + +#ifndef __DOCUMENTIMPORTER_H__ +#define __DOCUMENTIMPORTER_H__ struct Main; struct bContext; @@ -29,3 +32,5 @@ class DocumentImporter public: void import(bContext *C, const char *filename); }; + +#endif diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp new file mode 100644 index 00000000000..a210eb3b2e0 --- /dev/null +++ b/source/blender/collada/MeshImporter.cpp @@ -0,0 +1,907 @@ +/** + * $Id: DocumentImporter.cpp 32235 2010-10-01 19:46:42Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include + +#include "COLLADAFWMeshPrimitive.h" +#include "COLLADAFWMeshVertexData.h" +#include "COLLADAFWPolygons.h" + +extern "C" { +#include "BKE_blender.h" +#include "BKE_customdata.h" +#include "BKE_displist.h" +#include "BKE_global.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_material.h" +#include "BKE_mesh.h" +#include "BKE_object.h" + +#include "BLI_listbase.h" +#include "BLI_math.h" +#include "BLI_string.h" + +#include "MEM_guardedalloc.h" +} + +#include "ArmatureImporter.h" +#include "MeshImporter.h" +#include "collada_utils.h" + +// works for COLLADAFW::Node, COLLADAFW::Geometry +template +static const char *bc_get_dae_name(T *node) +{ + const std::string& name = node->getName(); + return name.size() ? name.c_str() : node->getOriginalId().c_str(); +} + +static const char *bc_primTypeToStr(COLLADAFW::MeshPrimitive::PrimitiveType type) +{ + switch (type) { + case COLLADAFW::MeshPrimitive::LINES: + return "LINES"; + case COLLADAFW::MeshPrimitive::LINE_STRIPS: + return "LINESTRIPS"; + case COLLADAFW::MeshPrimitive::POLYGONS: + return "POLYGONS"; + case COLLADAFW::MeshPrimitive::POLYLIST: + return "POLYLIST"; + case COLLADAFW::MeshPrimitive::TRIANGLES: + return "TRIANGLES"; + case COLLADAFW::MeshPrimitive::TRIANGLE_FANS: + return "TRIANGLE_FANS"; + case COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS: + return "TRIANGLE_FANS"; + case COLLADAFW::MeshPrimitive::POINTS: + return "POINTS"; + case COLLADAFW::MeshPrimitive::UNDEFINED_PRIMITIVE_TYPE: + return "UNDEFINED_PRIMITIVE_TYPE"; + } + return "UNKNOWN"; +} + +static const char *bc_geomTypeToStr(COLLADAFW::Geometry::GeometryType type) +{ + switch (type) { + case COLLADAFW::Geometry::GEO_TYPE_MESH: + return "MESH"; + case COLLADAFW::Geometry::GEO_TYPE_SPLINE: + return "SPLINE"; + case COLLADAFW::Geometry::GEO_TYPE_CONVEX_MESH: + return "CONVEX_MESH"; + case COLLADAFW::Geometry::GEO_TYPE_UNKNOWN: + default: + return "UNKNOWN"; + } +} + + +UVDataWrapper::UVDataWrapper(COLLADAFW::MeshVertexData& vdata) : mVData(&vdata) +{} + +#ifdef COLLADA_DEBUG +void WVDataWrapper::print() +{ + fprintf(stderr, "UVs:\n"); + switch(mVData->getType()) { + case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: + { + COLLADAFW::ArrayPrimitiveType* values = mVData->getFloatValues(); + if (values->getCount()) { + for (int i = 0; i < values->getCount(); i += 2) { + fprintf(stderr, "%.1f, %.1f\n", (*values)[i], (*values)[i+1]); + } + } + } + break; + case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE: + { + COLLADAFW::ArrayPrimitiveType* values = mVData->getDoubleValues(); + if (values->getCount()) { + for (int i = 0; i < values->getCount(); i += 2) { + fprintf(stderr, "%.1f, %.1f\n", (float)(*values)[i], (float)(*values)[i+1]); + } + } + } + break; + } + fprintf(stderr, "\n"); +} +#endif + +void UVDataWrapper::getUV(int uv_index[2], float *uv) +{ + switch(mVData->getType()) { + case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: + { + COLLADAFW::ArrayPrimitiveType* values = mVData->getFloatValues(); + if (values->empty()) return; + uv[0] = (*values)[uv_index[0]]; + uv[1] = (*values)[uv_index[1]]; + + } + break; + case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE: + { + COLLADAFW::ArrayPrimitiveType* values = mVData->getDoubleValues(); + if (values->empty()) return; + uv[0] = (float)(*values)[uv_index[0]]; + uv[1] = (float)(*values)[uv_index[1]]; + + } + break; + case COLLADAFW::MeshVertexData::DATA_TYPE_UNKNOWN: + default: + fprintf(stderr, "MeshImporter.getUV(): unknown data type\n"); + } +} + +void MeshImporter::set_face_indices(MFace *mface, unsigned int *indices, bool quad) +{ + mface->v1 = indices[0]; + mface->v2 = indices[1]; + mface->v3 = indices[2]; + if (quad) mface->v4 = indices[3]; + else mface->v4 = 0; +#ifdef COLLADA_DEBUG + // fprintf(stderr, "%u, %u, %u \n", indices[0], indices[1], indices[2]); +#endif +} + +// not used anymore, test_index_face from blenkernel is better +#if 0 +// change face indices order so that v4 is not 0 +void MeshImporter::rotate_face_indices(MFace *mface) { + mface->v4 = mface->v1; + mface->v1 = mface->v2; + mface->v2 = mface->v3; + mface->v3 = 0; +} +#endif + +void MeshImporter::set_face_uv(MTFace *mtface, UVDataWrapper &uvs, + COLLADAFW::IndexList& index_list, unsigned int *tris_indices) +{ + int uv_indices[4][2]; + + // per face vertex indices, this means for quad we have 4 indices, not 8 + COLLADAFW::UIntValuesArray& indices = index_list.getIndices(); + + // make indices into FloatOrDoubleArray + for (int i = 0; i < 3; i++) { + int uv_index = indices[tris_indices[i]]; + uv_indices[i][0] = uv_index * 2; + uv_indices[i][1] = uv_index * 2 + 1; + } + + uvs.getUV(uv_indices[0], mtface->uv[0]); + uvs.getUV(uv_indices[1], mtface->uv[1]); + uvs.getUV(uv_indices[2], mtface->uv[2]); +} + +void MeshImporter::set_face_uv(MTFace *mtface, UVDataWrapper &uvs, + COLLADAFW::IndexList& index_list, int index, bool quad) +{ + int uv_indices[4][2]; + + // per face vertex indices, this means for quad we have 4 indices, not 8 + COLLADAFW::UIntValuesArray& indices = index_list.getIndices(); + + // make indices into FloatOrDoubleArray + for (int i = 0; i < (quad ? 4 : 3); i++) { + int uv_index = indices[index + i]; + uv_indices[i][0] = uv_index * 2; + uv_indices[i][1] = uv_index * 2 + 1; + } + + uvs.getUV(uv_indices[0], mtface->uv[0]); + uvs.getUV(uv_indices[1], mtface->uv[1]); + uvs.getUV(uv_indices[2], mtface->uv[2]); + + if (quad) uvs.getUV(uv_indices[3], mtface->uv[3]); + +#ifdef COLLADA_DEBUG + /*if (quad) { + fprintf(stderr, "face uv:\n" + "((%d, %d), (%d, %d), (%d, %d), (%d, %d))\n" + "((%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f))\n", + + uv_indices[0][0], uv_indices[0][1], + uv_indices[1][0], uv_indices[1][1], + uv_indices[2][0], uv_indices[2][1], + uv_indices[3][0], uv_indices[3][1], + + mtface->uv[0][0], mtface->uv[0][1], + mtface->uv[1][0], mtface->uv[1][1], + mtface->uv[2][0], mtface->uv[2][1], + mtface->uv[3][0], mtface->uv[3][1]); + } + else { + fprintf(stderr, "face uv:\n" + "((%d, %d), (%d, %d), (%d, %d))\n" + "((%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f))\n", + + uv_indices[0][0], uv_indices[0][1], + uv_indices[1][0], uv_indices[1][1], + uv_indices[2][0], uv_indices[2][1], + + mtface->uv[0][0], mtface->uv[0][1], + mtface->uv[1][0], mtface->uv[1][1], + mtface->uv[2][0], mtface->uv[2][1]); + }*/ +#endif +} + +#ifdef COLLADA_DEBUG +void MeshImporter::print_index_list(COLLADAFW::IndexList& index_list) +{ + fprintf(stderr, "Index list for \"%s\":\n", index_list.getName().c_str()); + for (int i = 0; i < index_list.getIndicesCount(); i += 2) { + fprintf(stderr, "%u, %u\n", index_list.getIndex(i), index_list.getIndex(i + 1)); + } + fprintf(stderr, "\n"); +} +#endif + +bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh) +{ + COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives(); + + const char *name = bc_get_dae_name(mesh); + + for (unsigned i = 0; i < prim_arr.getCount(); i++) { + + COLLADAFW::MeshPrimitive *mp = prim_arr[i]; + COLLADAFW::MeshPrimitive::PrimitiveType type = mp->getPrimitiveType(); + + const char *type_str = bc_primTypeToStr(type); + + // OpenCollada passes POLYGONS type for + if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) { + + COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons*)mp; + COLLADAFW::Polygons::VertexCountArray& vca = mpvc->getGroupedVerticesVertexCountArray(); + + for(unsigned int j = 0; j < vca.getCount(); j++){ + int count = vca[j]; + if (count < 3) { + fprintf(stderr, "Primitive %s in %s has at least one face with vertex count < 3\n", + type_str, name); + return false; + } + } + + } + else if(type != COLLADAFW::MeshPrimitive::TRIANGLES) { + fprintf(stderr, "Primitive type %s is not supported.\n", type_str); + return false; + } + } + + if (mesh->getPositions().empty()) { + fprintf(stderr, "Mesh %s has no vertices.\n", name); + return false; + } + + return true; +} + +void MeshImporter::read_vertices(COLLADAFW::Mesh *mesh, Mesh *me) +{ + // vertices + me->totvert = mesh->getPositions().getFloatValues()->getCount() / 3; + me->mvert = (MVert*)CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert); + + COLLADAFW::MeshVertexData& pos = mesh->getPositions(); + MVert *mvert; + int i; + + for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) + get_vector(mvert->co, pos, i); +} + +int MeshImporter::triangulate_poly(unsigned int *indices, int totvert, MVert *verts, std::vector& tri) +{ + ListBase dispbase; + DispList *dl; + float *vert; + int i = 0; + + dispbase.first = dispbase.last = NULL; + + dl = (DispList*)MEM_callocN(sizeof(DispList), "poly disp"); + dl->nr = totvert; + dl->type = DL_POLY; + dl->parts = 1; + dl->verts = vert = (float*)MEM_callocN(totvert * 3 * sizeof(float), "poly verts"); + dl->index = (int*)MEM_callocN(sizeof(int) * 3 * totvert, "dl index"); + + BLI_addtail(&dispbase, dl); + + for (i = 0; i < totvert; i++) { + copy_v3_v3(vert, verts[indices[i]].co); + vert += 3; + } + + filldisplist(&dispbase, &dispbase, 0); + + int tottri = 0; + dl= (DispList*)dispbase.first; + + if (dl->type == DL_INDEX3) { + tottri = dl->parts; + + int *index = dl->index; + for (i= 0; i < tottri; i++) { + int t[3]= {*index, *(index + 1), *(index + 2)}; + + std::sort(t, t + 3); + + tri.push_back(t[0]); + tri.push_back(t[1]); + tri.push_back(t[2]); + + index += 3; + } + } + + freedisplist(&dispbase); + + return tottri; +} + +int MeshImporter::count_new_tris(COLLADAFW::Mesh *mesh, Mesh *me) +{ + COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives(); + unsigned int i; + int tottri = 0; + + for (i = 0; i < prim_arr.getCount(); i++) { + + COLLADAFW::MeshPrimitive *mp = prim_arr[i]; + int type = mp->getPrimitiveType(); + size_t prim_totface = mp->getFaceCount(); + unsigned int *indices = mp->getPositionIndices().getData(); + + if (type == COLLADAFW::MeshPrimitive::POLYLIST || + type == COLLADAFW::MeshPrimitive::POLYGONS) { + + COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons*)mp; + COLLADAFW::Polygons::VertexCountArray& vcounta = mpvc->getGroupedVerticesVertexCountArray(); + + for (unsigned int j = 0; j < prim_totface; j++) { + int vcount = vcounta[j]; + + if (vcount > 4) { + std::vector tri; + + // tottri += triangulate_poly(indices, vcount, me->mvert, tri) - 1; // XXX why - 1?! + tottri += triangulate_poly(indices, vcount, me->mvert, tri); + } + + indices += vcount; + } + } + } + return tottri; +} + +// TODO: import uv set names +void MeshImporter::read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris) +{ + unsigned int i; + + // allocate faces + me->totface = mesh->getFacesCount() + new_tris; + me->mface = (MFace*)CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface); + + // allocate UV layers + unsigned int totuvset = mesh->getUVCoords().getInputInfosArray().getCount(); + + for (i = 0; i < totuvset; i++) { + if (mesh->getUVCoords().getLength(i) == 0) { + totuvset = 0; + break; + } + } + + for (i = 0; i < totuvset; i++) { + COLLADAFW::MeshVertexData::InputInfos *info = mesh->getUVCoords().getInputInfosArray()[i]; + CustomData_add_layer_named(&me->fdata, CD_MTFACE, CD_CALLOC, NULL, me->totface, info->mName.c_str()); + //this->set_layername_map[i] = CustomData_get_layer_name(&me->fdata, CD_MTFACE, i); + } + + // activate the first uv layer + if (totuvset) me->mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, 0); + + UVDataWrapper uvs(mesh->getUVCoords()); + +#ifdef COLLADA_DEBUG + // uvs.print(); +#endif + + MFace *mface = me->mface; + + MaterialIdPrimitiveArrayMap mat_prim_map; + + int face_index = 0; + + COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives(); + + bool has_normals = mesh->hasNormals(); + COLLADAFW::MeshVertexData& nor = mesh->getNormals(); + + for (i = 0; i < prim_arr.getCount(); i++) { + + COLLADAFW::MeshPrimitive *mp = prim_arr[i]; + + // faces + size_t prim_totface = mp->getFaceCount(); + unsigned int *indices = mp->getPositionIndices().getData(); + unsigned int *nind = mp->getNormalIndices().getData(); + unsigned int j, k; + int type = mp->getPrimitiveType(); + int index = 0; + + // since we cannot set mface->mat_nr here, we store a portion of me->mface in Primitive + Primitive prim = {mface, 0}; + COLLADAFW::IndexListArray& index_list_array = mp->getUVCoordIndicesArray(); + +#ifdef COLLADA_DEBUG + /* + fprintf(stderr, "Primitive %d:\n", i); + for (int j = 0; j < totuvset; j++) { + print_index_list(*index_list_array[j]); + } + */ +#endif + + if (type == COLLADAFW::MeshPrimitive::TRIANGLES) { + for (j = 0; j < prim_totface; j++){ + + set_face_indices(mface, indices, false); + indices += 3; + +#if 0 + for (k = 0; k < totuvset; k++) { + if (!index_list_array.empty() && index_list_array[k]) { + // get mtface by face index and uv set index + MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k); + set_face_uv(&mtface[face_index], uvs, k, *index_list_array[k], index, false); + } + } +#else + for (k = 0; k < index_list_array.getCount(); k++) { + int uvset_index = index_list_array[k]->getSetIndex(); + + // get mtface by face index and uv set index + MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, uvset_index); + set_face_uv(&mtface[face_index], uvs, *index_list_array[k], index, false); + } +#endif + + test_index_face(mface, &me->fdata, face_index, 3); + + if (has_normals) { + if (!flat_face(nind, nor, 3)) + mface->flag |= ME_SMOOTH; + + nind += 3; + } + + index += 3; + mface++; + face_index++; + prim.totface++; + } + } + else if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) { + COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons*)mp; + COLLADAFW::Polygons::VertexCountArray& vcounta = mpvc->getGroupedVerticesVertexCountArray(); + + for (j = 0; j < prim_totface; j++) { + + // face + int vcount = vcounta[j]; + if (vcount == 3 || vcount == 4) { + + set_face_indices(mface, indices, vcount == 4); + + // set mtface for each uv set + // it is assumed that all primitives have equal number of UV sets + +#if 0 + for (k = 0; k < totuvset; k++) { + if (!index_list_array.empty() && index_list_array[k]) { + // get mtface by face index and uv set index + MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k); + set_face_uv(&mtface[face_index], uvs, k, *index_list_array[k], index, mface->v4 != 0); + } + } +#else + for (k = 0; k < index_list_array.getCount(); k++) { + int uvset_index = index_list_array[k]->getSetIndex(); + + // get mtface by face index and uv set index + MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, uvset_index); + set_face_uv(&mtface[face_index], uvs, *index_list_array[k], index, mface->v4 != 0); + } +#endif + + test_index_face(mface, &me->fdata, face_index, vcount); + + if (has_normals) { + if (!flat_face(nind, nor, vcount)) + mface->flag |= ME_SMOOTH; + + nind += vcount; + } + + mface++; + face_index++; + prim.totface++; + + } + else { + std::vector tri; + + triangulate_poly(indices, vcount, me->mvert, tri); + + for (k = 0; k < tri.size() / 3; k++) { + int v = k * 3; + unsigned int uv_indices[3] = { + index + tri[v], + index + tri[v + 1], + index + tri[v + 2] + }; + unsigned int tri_indices[3] = { + indices[tri[v]], + indices[tri[v + 1]], + indices[tri[v + 2]] + }; + + set_face_indices(mface, tri_indices, false); + +#if 0 + for (unsigned int l = 0; l < totuvset; l++) { + if (!index_list_array.empty() && index_list_array[l]) { + // get mtface by face index and uv set index + MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, l); + set_face_uv(&mtface[face_index], uvs, l, *index_list_array[l], uv_indices); + } + } +#else + for (unsigned int l = 0; l < index_list_array.getCount(); l++) { + int uvset_index = index_list_array[l]->getSetIndex(); + + // get mtface by face index and uv set index + MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, uvset_index); + set_face_uv(&mtface[face_index], uvs, *index_list_array[l], uv_indices); + } +#endif + + + test_index_face(mface, &me->fdata, face_index, 3); + + if (has_normals) { + unsigned int ntri[3] = {nind[tri[v]], nind[tri[v + 1]], nind[tri[v + 2]]}; + + if (!flat_face(ntri, nor, 3)) + mface->flag |= ME_SMOOTH; + } + + mface++; + face_index++; + prim.totface++; + } + + if (has_normals) + nind += vcount; + } + + index += vcount; + indices += vcount; + } + } + + mat_prim_map[mp->getMaterialId()].push_back(prim); + } + + geom_uid_mat_mapping_map[mesh->getUniqueId()] = mat_prim_map; +} + +void MeshImporter::get_vector(float v[3], COLLADAFW::MeshVertexData& arr, int i) +{ + i *= 3; + + switch(arr.getType()) { + case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: + { + COLLADAFW::ArrayPrimitiveType* values = arr.getFloatValues(); + if (values->empty()) return; + + v[0] = (*values)[i++]; + v[1] = (*values)[i++]; + v[2] = (*values)[i]; + } + break; + case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE: + { + COLLADAFW::ArrayPrimitiveType* values = arr.getDoubleValues(); + if (values->empty()) return; + + v[0] = (float)(*values)[i++]; + v[1] = (float)(*values)[i++]; + v[2] = (float)(*values)[i]; + } + break; + default: + break; + } +} + +bool MeshImporter::flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& nor, int count) +{ + float a[3], b[3]; + + get_vector(a, nor, *nind); + normalize_v3(a); + + nind++; + + for (int i = 1; i < count; i++, nind++) { + get_vector(b, nor, *nind); + normalize_v3(b); + + float dp = dot_v3v3(a, b); + + if (dp < 0.99999f || dp > 1.00001f) + return false; + } + + return true; +} + +MeshImporter::MeshImporter(ArmatureImporter *arm, Scene *sce) : scene(sce), armature_importer(arm) {} + +Object *MeshImporter::get_object_by_geom_uid(const COLLADAFW::UniqueId& geom_uid) +{ + if (uid_object_map.find(geom_uid) != uid_object_map.end()) + return uid_object_map[geom_uid]; + return NULL; +} + +MTex *MeshImporter::assign_textures_to_uvlayer(COLLADAFW::TextureCoordinateBinding &ctexture, + Mesh *me, TexIndexTextureArrayMap& texindex_texarray_map, + MTex *color_texture) +{ + const COLLADAFW::TextureMapId texture_index = ctexture.getTextureMapId(); + const size_t setindex = ctexture.getSetIndex(); + std::string uvname = ctexture.getName(); + + const CustomData *data = &me->fdata; + int layer_index = CustomData_get_layer_index(data, CD_MTFACE); + CustomDataLayer *cdl = &data->layers[layer_index+setindex]; + + /* set uvname to bind_vertex_input semantic */ + BLI_strncpy(cdl->name, uvname.c_str(), sizeof(cdl->name)); + + if (texindex_texarray_map.find(texture_index) == texindex_texarray_map.end()) { + + fprintf(stderr, "Cannot find texture array by texture index.\n"); + return color_texture; + } + + std::vector textures = texindex_texarray_map[texture_index]; + + std::vector::iterator it; + + for (it = textures.begin(); it != textures.end(); it++) { + + MTex *texture = *it; + + if (texture) { + BLI_strncpy(texture->uvname, uvname.c_str(), sizeof(texture->uvname)); + if (texture->mapto == MAP_COL) color_texture = texture; + } + } + return color_texture; +} + +MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial, + std::map& uid_material_map, + Object *ob, const COLLADAFW::UniqueId *geom_uid, + MTex **color_texture, char *layername, MTFace *texture_face, + std::map& material_texture_mapping_map, int mat_index) +{ + Mesh *me = (Mesh*)ob->data; + const COLLADAFW::UniqueId& ma_uid = cmaterial.getReferencedMaterial(); + + // do we know this material? + if (uid_material_map.find(ma_uid) == uid_material_map.end()) { + + fprintf(stderr, "Cannot find material by UID.\n"); + return NULL; + } + + Material *ma = uid_material_map[ma_uid]; + assign_material(ob, ma, ob->totcol + 1); + + COLLADAFW::TextureCoordinateBindingArray& tex_array = + cmaterial.getTextureCoordinateBindingArray(); + TexIndexTextureArrayMap texindex_texarray_map = material_texture_mapping_map[ma]; + unsigned int i; + // loop through + for (i = 0; i < tex_array.getCount(); i++) { + + *color_texture = assign_textures_to_uvlayer(tex_array[i], me, texindex_texarray_map, + *color_texture); + } + + // set texture face + if (*color_texture && + strlen((*color_texture)->uvname) && + strcmp(layername, (*color_texture)->uvname) != 0) { + + texture_face = (MTFace*)CustomData_get_layer_named(&me->fdata, CD_MTFACE, + (*color_texture)->uvname); + strcpy(layername, (*color_texture)->uvname); + } + + MaterialIdPrimitiveArrayMap& mat_prim_map = geom_uid_mat_mapping_map[*geom_uid]; + COLLADAFW::MaterialId mat_id = cmaterial.getMaterialId(); + + // assign material indices to mesh faces + if (mat_prim_map.find(mat_id) != mat_prim_map.end()) { + + std::vector& prims = mat_prim_map[mat_id]; + + std::vector::iterator it; + + for (it = prims.begin(); it != prims.end(); it++) { + Primitive& prim = *it; + i = 0; + while (i++ < prim.totface) { + prim.mface->mat_nr = mat_index; + prim.mface++; + // bind texture images to faces + if (texture_face && (*color_texture)) { + texture_face->mode = TF_TEX; + texture_face->tpage = (Image*)(*color_texture)->tex->ima; + texture_face++; + } + } + } + } + + return texture_face; +} + + +Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom, + bool isController, + std::map& uid_material_map, + std::map& material_texture_mapping_map) +{ + const COLLADAFW::UniqueId *geom_uid = &geom->getInstanciatedObjectId(); + + // check if node instanciates controller or geometry + if (isController) { + + geom_uid = armature_importer->get_geometry_uid(*geom_uid); + + if (!geom_uid) { + fprintf(stderr, "Couldn't find a mesh UID by controller's UID.\n"); + return NULL; + } + } + else { + + if (uid_mesh_map.find(*geom_uid) == uid_mesh_map.end()) { + // this could happen if a mesh was not created + // (e.g. if it contains unsupported geometry) + fprintf(stderr, "Couldn't find a mesh by UID.\n"); + return NULL; + } + } + if (!uid_mesh_map[*geom_uid]) return NULL; + + Object *ob = add_object(scene, OB_MESH); + + // store object pointer for ArmatureImporter + uid_object_map[*geom_uid] = ob; + + // name Object + const std::string& id = node->getOriginalId(); + if (id.length()) + rename_id(&ob->id, (char*)id.c_str()); + + // replace ob->data freeing the old one + Mesh *old_mesh = (Mesh*)ob->data; + + set_mesh(ob, uid_mesh_map[*geom_uid]); + + if (old_mesh->id.us == 0) free_libblock(&G.main->mesh, old_mesh); + + char layername[100]; + MTFace *texture_face = NULL; + MTex *color_texture = NULL; + + COLLADAFW::MaterialBindingArray& mat_array = + geom->getMaterialBindings(); + + // loop through geom's materials + for (unsigned int i = 0; i < mat_array.getCount(); i++) { + + texture_face = assign_material_to_geom(mat_array[i], uid_material_map, ob, geom_uid, + &color_texture, layername, texture_face, + material_texture_mapping_map, i); + } + + return ob; +} + +// create a mesh storing a pointer in a map so it can be retrieved later by geometry UID +bool MeshImporter::write_geometry(const COLLADAFW::Geometry* geom) +{ + // TODO: import also uvs, normals + // XXX what to do with normal indices? + // XXX num_normals may be != num verts, then what to do? + + // check geometry->getType() first + if (geom->getType() != COLLADAFW::Geometry::GEO_TYPE_MESH) { + // TODO: report warning + fprintf(stderr, "Mesh type %s is not supported\n", bc_geomTypeToStr(geom->getType())); + return true; + } + + COLLADAFW::Mesh *mesh = (COLLADAFW::Mesh*)geom; + + if (!is_nice_mesh(mesh)) { + fprintf(stderr, "Ignoring mesh %s\n", bc_get_dae_name(mesh)); + return true; + } + + const std::string& str_geom_id = mesh->getOriginalId(); + Mesh *me = add_mesh((char*)str_geom_id.c_str()); + + // store the Mesh pointer to link it later with an Object + this->uid_mesh_map[mesh->getUniqueId()] = me; + + int new_tris = 0; + + read_vertices(mesh, me); + + new_tris = count_new_tris(mesh, me); + + read_faces(mesh, me, new_tris); + + make_edges(me, 0); + + mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); + + return true; +} diff --git a/source/blender/collada/MeshImporter.h b/source/blender/collada/MeshImporter.h new file mode 100644 index 00000000000..8c468b01fb6 --- /dev/null +++ b/source/blender/collada/MeshImporter.h @@ -0,0 +1,150 @@ +/** + * $Id: DocumentImporter.cpp 32235 2010-10-01 19:46:42Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BC__MESHIMPORTER_H__ +#define __BC__MESHIMPORTER_H__ + +#include +#include + +#include "COLLADAFWIndexList.h" +#include "COLLADAFWInstanceGeometry.h" +#include "COLLADAFWMaterialBinding.h" +#include "COLLADAFWMesh.h" +#include "COLLADAFWMeshVertexData.h" +#include "COLLADAFWNode.h" +#include "COLLADAFWTextureCoordinateBinding.h" +#include "COLLADAFWTypes.h" +#include "COLLADAFWUniqueId.h" + +#include "DNA_material_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_texture_types.h" + +#include "ArmatureImporter.h" +#include "collada_utils.h" + +// only for ArmatureImporter to "see" MeshImporter::get_object_by_geom_uid +class MeshImporterBase +{ +public: + virtual Object *get_object_by_geom_uid(const COLLADAFW::UniqueId& geom_uid) = 0; +}; + +class UVDataWrapper +{ + COLLADAFW::MeshVertexData *mVData; +public: + UVDataWrapper(COLLADAFW::MeshVertexData& vdata); + +#ifdef COLLADA_DEBUG + void print(); +#endif + + void getUV(int uv_index[2], float *uv); +}; + +class MeshImporter : public MeshImporterBase +{ +private: + + Scene *scene; + ArmatureImporter *armature_importer; + + std::map uid_mesh_map; // geometry unique id-to-mesh map + std::map uid_object_map; // geom uid-to-object + // this structure is used to assign material indices to faces + // it holds a portion of Mesh faces and corresponds to a DAE primitive list (, , etc.) + struct Primitive { + MFace *mface; + unsigned int totface; + }; + typedef std::map > MaterialIdPrimitiveArrayMap; + std::map geom_uid_mat_mapping_map; // crazy name! + + + void set_face_indices(MFace *mface, unsigned int *indices, bool quad); + + // not used anymore, test_index_face from blenkernel is better +#if 0 + // change face indices order so that v4 is not 0 + void rotate_face_indices(MFace *mface); +#endif + + void set_face_uv(MTFace *mtface, UVDataWrapper &uvs, + COLLADAFW::IndexList& index_list, unsigned int *tris_indices); + + void set_face_uv(MTFace *mtface, UVDataWrapper &uvs, + COLLADAFW::IndexList& index_list, int index, bool quad); + +#ifdef COLLADA_DEBUG + void print_index_list(COLLADAFW::IndexList& index_list); +#endif + + bool is_nice_mesh(COLLADAFW::Mesh *mesh); + + void read_vertices(COLLADAFW::Mesh *mesh, Mesh *me); + + int triangulate_poly(unsigned int *indices, int totvert, MVert *verts, std::vector& tri); + + int count_new_tris(COLLADAFW::Mesh *mesh, Mesh *me); + + // TODO: import uv set names + void read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris); + + void get_vector(float v[3], COLLADAFW::MeshVertexData& arr, int i); + + bool flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& nor, int count); + +public: + + MeshImporter(ArmatureImporter *arm, Scene *sce); + + virtual Object *get_object_by_geom_uid(const COLLADAFW::UniqueId& geom_uid); + + MTex *assign_textures_to_uvlayer(COLLADAFW::TextureCoordinateBinding &ctexture, + Mesh *me, TexIndexTextureArrayMap& texindex_texarray_map, + MTex *color_texture); + + MTFace *assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial, + std::map& uid_material_map, + Object *ob, const COLLADAFW::UniqueId *geom_uid, + MTex **color_texture, char *layername, MTFace *texture_face, + std::map& material_texture_mapping_map, int mat_index); + + + Object *create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom, + bool isController, + std::map& uid_material_map, + std::map& material_texture_mapping_map); + + // create a mesh storing a pointer in a map so it can be retrieved later by geometry UID + bool write_geometry(const COLLADAFW::Geometry* geom); + +}; + +#endif diff --git a/source/blender/collada/SkinInfo.cpp b/source/blender/collada/SkinInfo.cpp new file mode 100644 index 00000000000..db6a7a62b54 --- /dev/null +++ b/source/blender/collada/SkinInfo.cpp @@ -0,0 +1,320 @@ +/** + * $Id: DocumentImporter.cpp 32235 2010-10-01 19:46:42Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include + +#include "BKE_object.h" +#include "DNA_armature_types.h" +#include "DNA_modifier_types.h" +#include "ED_mesh.h" +#include "ED_object.h" +#include "BKE_action.h" +#include "BLI_listbase.h" +#include "BLI_math.h" + +#include "SkinInfo.h" +#include "collada_utils.h" + +// use this for retrieving bone names, since these must be unique +template +static const char *bc_get_joint_name(T *node) +{ + const std::string& id = node->getOriginalId(); + return id.size() ? id.c_str() : node->getName().c_str(); +} + +// This is used to store data passed in write_controller_data. +// Arrays from COLLADAFW::SkinControllerData lose ownership, so do this class members +// so that arrays don't get freed until we free them explicitly. +SkinInfo::SkinInfo() {} + +SkinInfo::SkinInfo(const SkinInfo& skin) : weights(skin.weights), + joint_data(skin.joint_data), + unit_converter(skin.unit_converter), + ob_arm(skin.ob_arm), + controller_uid(skin.controller_uid), + parent(skin.parent) +{ + copy_m4_m4(bind_shape_matrix, (float (*)[4])skin.bind_shape_matrix); + + transfer_uint_array_data_const(skin.joints_per_vertex, joints_per_vertex); + transfer_uint_array_data_const(skin.weight_indices, weight_indices); + transfer_int_array_data_const(skin.joint_indices, joint_indices); +} + +SkinInfo::SkinInfo(UnitConverter *conv) : unit_converter(conv), ob_arm(NULL), parent(NULL) {} + +// nobody owns the data after this, so it should be freed manually with releaseMemory +template +void SkinInfo::transfer_array_data(T& src, T& dest) +{ + dest.setData(src.getData(), src.getCount()); + src.yieldOwnerShip(); + dest.yieldOwnerShip(); +} + +// when src is const we cannot src.yieldOwnerShip, this is used by copy constructor +void SkinInfo::transfer_int_array_data_const(const COLLADAFW::IntValuesArray& src, COLLADAFW::IntValuesArray& dest) +{ + dest.setData((int*)src.getData(), src.getCount()); + dest.yieldOwnerShip(); +} + +void SkinInfo::transfer_uint_array_data_const(const COLLADAFW::UIntValuesArray& src, COLLADAFW::UIntValuesArray& dest) +{ + dest.setData((unsigned int*)src.getData(), src.getCount()); + dest.yieldOwnerShip(); +} + +void SkinInfo::borrow_skin_controller_data(const COLLADAFW::SkinControllerData* skin) +{ + transfer_array_data((COLLADAFW::UIntValuesArray&)skin->getJointsPerVertex(), joints_per_vertex); + transfer_array_data((COLLADAFW::UIntValuesArray&)skin->getWeightIndices(), weight_indices); + transfer_array_data((COLLADAFW::IntValuesArray&)skin->getJointIndices(), joint_indices); + // transfer_array_data(skin->getWeights(), weights); + + // cannot transfer data for FloatOrDoubleArray, copy values manually + const COLLADAFW::FloatOrDoubleArray& weight = skin->getWeights(); + for (unsigned int i = 0; i < weight.getValuesCount(); i++) + weights.push_back(bc_get_float_value(weight, i)); + + unit_converter->dae_matrix_to_mat4_(bind_shape_matrix, skin->getBindShapeMatrix()); +} + +void SkinInfo::free() +{ + joints_per_vertex.releaseMemory(); + weight_indices.releaseMemory(); + joint_indices.releaseMemory(); + // weights.releaseMemory(); +} + +// using inverse bind matrices to construct armature +// it is safe to invert them to get the original matrices +// because if they are inverse matrices, they can be inverted +void SkinInfo::add_joint(const COLLADABU::Math::Matrix4& matrix) +{ + JointData jd; + unit_converter->dae_matrix_to_mat4_(jd.inv_bind_mat, matrix); + joint_data.push_back(jd); +} + +void SkinInfo::set_controller(const COLLADAFW::SkinController* co) +{ + controller_uid = co->getUniqueId(); + + // fill in joint UIDs + const COLLADAFW::UniqueIdArray& joint_uids = co->getJoints(); + for (unsigned int i = 0; i < joint_uids.getCount(); i++) { + joint_data[i].joint_uid = joint_uids[i]; + + // // store armature pointer + // JointData& jd = joint_index_to_joint_info_map[i]; + // jd.ob_arm = ob_arm; + + // now we'll be able to get inv bind matrix from joint id + // joint_id_to_joint_index_map[joint_ids[i]] = i; + } +} + +// called from write_controller +Object *SkinInfo::create_armature(Scene *scene) +{ + ob_arm = add_object(scene, OB_ARMATURE); + return ob_arm; +} + +Object* SkinInfo::set_armature(Object *ob_arm) +{ + if (this->ob_arm) + return this->ob_arm; + + this->ob_arm = ob_arm; + return ob_arm; +} + +bool SkinInfo::get_joint_inv_bind_matrix(float inv_bind_mat[][4], COLLADAFW::Node *node) +{ + const COLLADAFW::UniqueId& uid = node->getUniqueId(); + std::vector::iterator it; + for (it = joint_data.begin(); it != joint_data.end(); it++) { + if ((*it).joint_uid == uid) { + copy_m4_m4(inv_bind_mat, (*it).inv_bind_mat); + return true; + } + } + + return false; +} + +Object *SkinInfo::get_armature() +{ + return ob_arm; +} + +const COLLADAFW::UniqueId& SkinInfo::get_controller_uid() +{ + return controller_uid; +} + +// check if this skin controller references a joint or any descendant of it +// +// some nodes may not be referenced by SkinController, +// in this case to determine if the node belongs to this armature, +// we need to search down the tree +bool SkinInfo::uses_joint_or_descendant(COLLADAFW::Node *node) +{ + const COLLADAFW::UniqueId& uid = node->getUniqueId(); + std::vector::iterator it; + for (it = joint_data.begin(); it != joint_data.end(); it++) { + if ((*it).joint_uid == uid) + return true; + } + + COLLADAFW::NodePointerArray& children = node->getChildNodes(); + for (unsigned int i = 0; i < children.getCount(); i++) { + if (uses_joint_or_descendant(children[i])) + return true; + } + + return false; +} + +void SkinInfo::link_armature(bContext *C, Object *ob, std::map& joint_by_uid, + TransformReader *tm) +{ + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + + ModifierData *md = ED_object_modifier_add(NULL, bmain, scene, ob, NULL, eModifierType_Armature); + ((ArmatureModifierData *)md)->object = ob_arm; + + copy_m4_m4(ob->obmat, bind_shape_matrix); + object_apply_mat4(ob, ob->obmat); +#if 1 + bc_set_parent(ob, ob_arm, C); +#else + Object workob; + ob->parent = ob_arm; + ob->partype = PAROBJECT; + + what_does_parent(scene, ob, &workob); + invert_m4_m4(ob->parentinv, workob.obmat); + + ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA; + + DAG_scene_sort(bmain, scene); + DAG_ids_flush_update(bmain, 0); + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); +#endif + + ((bArmature*)ob_arm->data)->deformflag = ARM_DEF_VGROUP; + + // create all vertex groups + std::vector::iterator it; + int joint_index; + for (it = joint_data.begin(), joint_index = 0; it != joint_data.end(); it++, joint_index++) { + const char *name = "Group"; + + // name group by joint node name + if (joint_by_uid.find((*it).joint_uid) != joint_by_uid.end()) { + name = bc_get_joint_name(joint_by_uid[(*it).joint_uid]); + } + + ED_vgroup_add_name(ob, (char*)name); + } + + // - number of joints per vertex - joints_per_vertex + // - [[bone index, weight index] * joints per vertex] * vertices - weight indices + // ^ bone index can be -1 meaning weight toward bind shape, how to express this in Blender? + + // for each vertex in weight indices + // for each bone index in vertex + // add vertex to group at group index + // treat group index -1 specially + + // get def group by index with BLI_findlink + + for (unsigned int vertex = 0, weight = 0; vertex < joints_per_vertex.getCount(); vertex++) { + + unsigned int limit = weight + joints_per_vertex[vertex]; + for ( ; weight < limit; weight++) { + int joint = joint_indices[weight], joint_weight = weight_indices[weight]; + + // -1 means "weight towards the bind shape", we just don't assign it to any group + if (joint != -1) { + bDeformGroup *def = (bDeformGroup*)BLI_findlink(&ob->defbase, joint); + + ED_vgroup_vert_add(ob, def, vertex, weights[joint_weight], WEIGHT_REPLACE); + } + } + } +} + +bPoseChannel *SkinInfo::get_pose_channel_from_node(COLLADAFW::Node *node) +{ + return get_pose_channel(ob_arm->pose, bc_get_joint_name(node)); +} + +void SkinInfo::set_parent(Object *_parent) +{ + parent = _parent; +} + +Object* SkinInfo::get_parent() +{ + return parent; +} + +void SkinInfo::find_root_joints(const std::vector &root_joints, + std::map& joint_by_uid, + std::vector& result) +{ + std::vector::const_iterator it; + for (it = root_joints.begin(); it != root_joints.end(); it++) { + COLLADAFW::Node *root = *it; + std::vector::iterator ji; + for (ji = joint_data.begin(); ji != joint_data.end(); ji++) { + COLLADAFW::Node *joint = joint_by_uid[(*ji).joint_uid]; + if (find_node_in_tree(joint, root)) { + if (std::find(result.begin(), result.end(), root) == result.end()) + result.push_back(root); + } + } + } +} + +bool SkinInfo::find_node_in_tree(COLLADAFW::Node *node, COLLADAFW::Node *tree_root) +{ + if (node == tree_root) + return true; + + COLLADAFW::NodePointerArray& children = tree_root->getChildNodes(); + for (unsigned int i = 0; i < children.getCount(); i++) { + if (find_node_in_tree(node, children[i])) + return true; + } + + return false; +} \ No newline at end of file diff --git a/source/blender/collada/SkinInfo.h b/source/blender/collada/SkinInfo.h new file mode 100644 index 00000000000..b7b87494be6 --- /dev/null +++ b/source/blender/collada/SkinInfo.h @@ -0,0 +1,133 @@ +/** + * $Id: DocumentImporter.cpp 32235 2010-10-01 19:46:42Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BC_SKININFO_H__ +#define __BC_SKININFO_H__ + +#include +#include + +#include "COLLADAFWUniqueId.h" +#include "COLLADAFWTypes.h" +#include "COLLADAFWNode.h" +#include "COLLADAFWSkinController.h" +#include "COLLADAFWSkinControllerData.h" + +#include "DNA_object_types.h" +#include "BKE_context.h" + +#include "TransformReader.h" +#include "collada_internal.h" + +// This is used to store data passed in write_controller_data. +// Arrays from COLLADAFW::SkinControllerData lose ownership, so do this class members +// so that arrays don't get freed until we free them explicitly. +class SkinInfo +{ +private: + // to build armature bones from inverse bind matrices + struct JointData { + float inv_bind_mat[4][4]; // joint inverse bind matrix + COLLADAFW::UniqueId joint_uid; // joint node UID + // Object *ob_arm; // armature object + }; + + float bind_shape_matrix[4][4]; + + // data from COLLADAFW::SkinControllerData, each array should be freed + COLLADAFW::UIntValuesArray joints_per_vertex; + COLLADAFW::UIntValuesArray weight_indices; + COLLADAFW::IntValuesArray joint_indices; + // COLLADAFW::FloatOrDoubleArray weights; + std::vector weights; + + std::vector joint_data; // index to this vector is joint index + + UnitConverter *unit_converter; + + Object *ob_arm; + COLLADAFW::UniqueId controller_uid; + Object *parent; + +public: + + SkinInfo(); + SkinInfo(const SkinInfo& skin); + SkinInfo(UnitConverter *conv); + + // nobody owns the data after this, so it should be freed manually with releaseMemory + template + void transfer_array_data(T& src, T& dest); + + // when src is const we cannot src.yieldOwnerShip, this is used by copy constructor + void transfer_int_array_data_const(const COLLADAFW::IntValuesArray& src, COLLADAFW::IntValuesArray& dest); + + void transfer_uint_array_data_const(const COLLADAFW::UIntValuesArray& src, COLLADAFW::UIntValuesArray& dest); + + void borrow_skin_controller_data(const COLLADAFW::SkinControllerData* skin); + + void free(); + + // using inverse bind matrices to construct armature + // it is safe to invert them to get the original matrices + // because if they are inverse matrices, they can be inverted + void add_joint(const COLLADABU::Math::Matrix4& matrix); + + void set_controller(const COLLADAFW::SkinController* co); + + // called from write_controller + Object *create_armature(Scene *scene); + + Object* set_armature(Object *ob_arm); + + bool get_joint_inv_bind_matrix(float inv_bind_mat[][4], COLLADAFW::Node *node); + + Object *get_armature(); + + const COLLADAFW::UniqueId& get_controller_uid(); + + // check if this skin controller references a joint or any descendant of it + // + // some nodes may not be referenced by SkinController, + // in this case to determine if the node belongs to this armature, + // we need to search down the tree + bool uses_joint_or_descendant(COLLADAFW::Node *node); + + void link_armature(bContext *C, Object *ob, std::map& joint_by_uid, TransformReader *tm); + + bPoseChannel *get_pose_channel_from_node(COLLADAFW::Node *node); + + void set_parent(Object *_parent); + + Object* get_parent(); + + void find_root_joints(const std::vector &root_joints, + std::map& joint_by_uid, + std::vector& result); + + bool find_node_in_tree(COLLADAFW::Node *node, COLLADAFW::Node *tree_root); + +}; + +#endif \ No newline at end of file diff --git a/source/blender/collada/TransformReader.cpp b/source/blender/collada/TransformReader.cpp new file mode 100644 index 00000000000..d951bfb6474 --- /dev/null +++ b/source/blender/collada/TransformReader.cpp @@ -0,0 +1,125 @@ +/** + * $Id: DocumentImporter.cpp 32235 2010-10-01 19:46:42Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "TransformReader.h" + +TransformReader::TransformReader(UnitConverter* conv) : unit_converter(conv) {} + +void TransformReader::get_node_mat(float mat[][4], COLLADAFW::Node *node, std::map *animation_map, Object *ob) +{ + float cur[4][4]; + float copy[4][4]; + + unit_m4(mat); + + for (unsigned int i = 0; i < node->getTransformations().getCount(); i++) { + + COLLADAFW::Transformation *tm = node->getTransformations()[i]; + COLLADAFW::Transformation::TransformationType type = tm->getTransformationType(); + + switch(type) { + case COLLADAFW::Transformation::TRANSLATE: + dae_translate_to_mat4(tm, cur); + break; + case COLLADAFW::Transformation::ROTATE: + dae_rotate_to_mat4(tm, cur); + break; + case COLLADAFW::Transformation::SCALE: + dae_scale_to_mat4(tm, cur); + break; + case COLLADAFW::Transformation::MATRIX: + dae_matrix_to_mat4(tm, cur); + break; + case COLLADAFW::Transformation::LOOKAT: + case COLLADAFW::Transformation::SKEW: + fprintf(stderr, "LOOKAT and SKEW transformations are not supported yet.\n"); + break; + } + + copy_m4_m4(copy, mat); + mul_m4_m4m4(mat, cur, copy); + + if (animation_map) { + // AnimationList that drives this Transformation + const COLLADAFW::UniqueId& anim_list_id = tm->getAnimationList(); + + // store this so later we can link animation data with ob + Animation anim = {ob, node, tm}; + (*animation_map)[anim_list_id] = anim; + } + } +} + +void TransformReader::dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[][4]) +{ + COLLADAFW::Rotate *ro = (COLLADAFW::Rotate*)tm; + COLLADABU::Math::Vector3& axis = ro->getRotationAxis(); + float angle = (float)(ro->getRotationAngle() * M_PI / 180.0f); + float ax[] = {axis[0], axis[1], axis[2]}; + // float quat[4]; + // axis_angle_to_quat(quat, axis, angle); + // quat_to_mat4(m, quat); + axis_angle_to_mat4(m, ax, angle); +} + +void TransformReader::dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[][4]) +{ + COLLADAFW::Translate *tra = (COLLADAFW::Translate*)tm; + COLLADABU::Math::Vector3& t = tra->getTranslation(); + + unit_m4(m); + + m[3][0] = (float)t[0]; + m[3][1] = (float)t[1]; + m[3][2] = (float)t[2]; +} + +void TransformReader::dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[][4]) +{ + COLLADABU::Math::Vector3& s = ((COLLADAFW::Scale*)tm)->getScale(); + float size[3] = {(float)s[0], (float)s[1], (float)s[2]}; + size_to_mat4(m, size); +} + +void TransformReader::dae_matrix_to_mat4(COLLADAFW::Transformation *tm, float m[][4]) +{ + unit_converter->dae_matrix_to_mat4_(m, ((COLLADAFW::Matrix*)tm)->getMatrix()); +} + +void TransformReader::dae_translate_to_v3(COLLADAFW::Transformation *tm, float v[3]) +{ + dae_vector3_to_v3(((COLLADAFW::Translate*)tm)->getTranslation(), v); +} + +void TransformReader::dae_scale_to_v3(COLLADAFW::Transformation *tm, float v[3]) +{ + dae_vector3_to_v3(((COLLADAFW::Scale*)tm)->getScale(), v); +} + +void TransformReader::dae_vector3_to_v3(const COLLADABU::Math::Vector3 &v3, float v[3]) +{ + v[0] = v3.x; + v[1] = v3.y; + v[2] = v3.z; +} \ No newline at end of file diff --git a/source/blender/collada/TransformReader.h b/source/blender/collada/TransformReader.h new file mode 100644 index 00000000000..fa08df1d4fa --- /dev/null +++ b/source/blender/collada/TransformReader.h @@ -0,0 +1,70 @@ +/** + * $Id: DocumentImporter.cpp 32235 2010-10-01 19:46:42Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BC_TRANSFORMREADER_H__ +#define __BC_TRANSFORMREADER_H__ + +#include "COLLADAFWNode.h" +#include "COLLADAFWTransformation.h" +#include "COLLADAFWTranslate.h" +#include "COLLADAFWRotate.h" +#include "COLLADAFWScale.h" +#include "COLLADAFWMatrix.h" +#include "COLLADAFWUniqueId.h" +#include "Math/COLLADABUMathVector3.h" + +#include "DNA_object_types.h" +#include "BLI_math.h" + +#include "collada_internal.h" + +//struct Object; + +class TransformReader : public TransformBase +{ +protected: + + UnitConverter *unit_converter; + +public: + struct Animation { + Object *ob; + COLLADAFW::Node *node; + COLLADAFW::Transformation *tm; // which transform is animated by an AnimationList->id + }; + + TransformReader(UnitConverter* conv); + + void get_node_mat(float mat[][4], COLLADAFW::Node *node, std::map *animation_map, Object *ob); + + void dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[][4]); + void dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[][4]); + void dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[][4]); + void dae_matrix_to_mat4(COLLADAFW::Transformation *tm, float m[][4]); + void dae_translate_to_v3(COLLADAFW::Transformation *tm, float v[3]); + void dae_scale_to_v3(COLLADAFW::Transformation *tm, float v[3]); + void dae_vector3_to_v3(const COLLADABU::Math::Vector3 &v3, float v[3]); +}; + +#endif \ No newline at end of file diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp index a519db3332c..d499249cfa2 100644 --- a/source/blender/collada/collada.cpp +++ b/source/blender/collada/collada.cpp @@ -21,15 +21,15 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#include "BKE_main.h" -#include "BKE_scene.h" -#include "BKE_context.h" #include "DocumentExporter.h" #include "DocumentImporter.h" extern "C" { +#include "BKE_scene.h" +#include "BKE_context.h" + int collada_import(bContext *C, const char *filepath) { DocumentImporter imp; diff --git a/source/blender/collada/collada_internal.h b/source/blender/collada/collada_internal.h index 242fce749c4..f8fbe71e6d9 100644 --- a/source/blender/collada/collada_internal.h +++ b/source/blender/collada/collada_internal.h @@ -27,6 +27,8 @@ #include "COLLADAFWFileInfo.h" #include "Math/COLLADABUMathMatrix4.h" +#include "BLI_math.h" + class UnitConverter { private: @@ -35,6 +37,7 @@ private: public: + // Initialize with Z_UP, since Blender uses right-handed, z-up UnitConverter() : unit(), up_axis(COLLADAFW::FileInfo::Z_UP) {} void read_asset(const COLLADAFW::FileInfo* asset) @@ -49,7 +52,7 @@ public: // TODO need also for angle conversion, time conversion... - void dae_matrix_to_mat4(float out[][4], const COLLADABU::Math::Matrix4& in) + void dae_matrix_to_mat4_(float out[][4], const COLLADABU::Math::Matrix4& in) { // in DAE, matrices use columns vectors, (see comments in COLLADABUMathMatrix4.h) // so here, to make a blender matrix, we swap columns and rows @@ -84,10 +87,12 @@ public: void decompose(float mat[][4], float *loc, float eul[3], float quat[4], float *size) { mat4_to_size(size, mat); - if (eul) + if (eul) { mat4_to_eul(eul, mat); - if (quat) + } + if (quat) { mat4_to_quat(quat, mat); + } copy_v3_v3(loc, mat[3]); } }; diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp new file mode 100644 index 00000000000..ec0bc91ee0b --- /dev/null +++ b/source/blender/collada/collada_utils.cpp @@ -0,0 +1,106 @@ +/** + * $Id: DocumentImporter.cpp 32235 2010-10-01 19:46:42Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "COLLADAFWGeometry.h" +#include "COLLADAFWMeshPrimitive.h" +#include "COLLADAFWMeshVertexData.h" + +#include "DNA_customdata_types.h" +#include "DNA_object_types.h" + +#include "BLI_math.h" + +#include "BKE_context.h" +#include "BKE_customdata.h" +#include "BKE_depsgraph.h" +#include "BKE_object.h" + +#include "WM_api.h" // XXX hrm, see if we can do without this +#include "WM_types.h" + +float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray& array, unsigned int index) +{ + if (index >= array.getValuesCount()) + return 0.0f; + + if (array.getType() == COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT) + return array.getFloatValues()->getData()[index]; + else + return array.getDoubleValues()->getData()[index]; +} + +// copied from /editors/object/object_relations.c +int bc_test_parent_loop(Object *par, Object *ob) +{ + /* test if 'ob' is a parent somewhere in par's parents */ + + if(par == NULL) return 0; + if(ob == par) return 1; + + return bc_test_parent_loop(par->parent, ob); +} + +// a shortened version of parent_set_exec() +// if is_parent_space is true then ob->obmat will be multiplied by par->obmat before parenting +int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space) +{ + Object workob; + Main *bmain = CTX_data_main(C); + Scene *sce = CTX_data_scene(C); + + if (!par || bc_test_parent_loop(par, ob)) + return false; + + ob->parent = par; + ob->partype = PAROBJECT; + + ob->parsubstr[0] = 0; + + if (is_parent_space) { + float mat[4][4]; + // calc par->obmat + where_is_object(sce, par); + + // move child obmat into world space + mul_m4_m4m4(mat, ob->obmat, par->obmat); + copy_m4_m4(ob->obmat, mat); + } + + // apply child obmat (i.e. decompose it into rot/loc/size) + object_apply_mat4(ob, ob->obmat); + + // compute parentinv + what_does_parent(sce, ob, &workob); + invert_m4_m4(ob->parentinv, workob.obmat); + + ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA; + par->recalc |= OB_RECALC_OB; + + DAG_scene_sort(bmain, sce); + DAG_ids_flush_update(bmain, 0); + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + + return true; +} + diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h new file mode 100644 index 00000000000..dbcbfdafec8 --- /dev/null +++ b/source/blender/collada/collada_utils.h @@ -0,0 +1,50 @@ +/** + * $Id: DocumentImporter.cpp 32235 2010-10-01 19:46:42Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BC_UTILS_H__ +#define __BC_UTILS_H__ + +#include "COLLADAFWMeshPrimitive.h" +#include "COLLADAFWGeometry.h" +#include "COLLADAFWFloatOrDoubleArray.h" +#include "COLLADAFWTypes.h" + +#include +#include + +#include "DNA_object_types.h" +#include "DNA_customdata_types.h" +#include "DNA_texture_types.h" +#include "BKE_context.h" + +typedef std::map > TexIndexTextureArrayMap; + +extern float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray& array, unsigned int index); + +extern int bc_test_parent_loop(Object *par, Object *ob); +extern int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space=true); +extern char *bc_CustomData_get_layer_name(const CustomData *data, int type, int n); +extern char *bc_CustomData_get_active_layer_name(const CustomData *data, int type); + +#endif diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 6055b9eecb3..474b50540d8 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -27,6 +27,10 @@ #ifndef ED_ARMATURE_H #define ED_ARMATURE_H +#ifdef __cplusplus +extern "C" { +#endif + struct bArmature; struct Base; struct bContext; @@ -168,6 +172,10 @@ int BDR_drawSketchNames(struct ViewContext *vc); void mesh_deform_bind(struct Scene *scene, struct MeshDeformModifierData *mmd, float *vertexcos, int totvert, float cagemat[][4]); + +#ifdef __cplusplus +} +#endif #endif /* ED_ARMATURE_H */ diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h index 8718d39dd18..b3aac489852 100644 --- a/source/blender/editors/include/ED_keyframing.h +++ b/source/blender/editors/include/ED_keyframing.h @@ -28,6 +28,10 @@ #ifndef ED_KEYFRAMING_H #define ED_KEYFRAMING_H +#ifdef __cplusplus +extern "C" { +#endif + struct ListBase; struct ID; struct Scene; @@ -280,4 +284,8 @@ typedef enum eAnimFilterFlags { ANIMFILTER_KEYS_NOSKEY = (1<<10), /* don't include shape keys (for geometry) */ } eAnimFilterFlags; +#ifdef __cplusplus +} +#endif + #endif /* ED_KEYFRAMING_H */ diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 564fe04ca4d..c4477ee5a8e 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -28,6 +28,10 @@ #ifndef ED_MESH_H #define ED_MESH_H +#ifdef __cplusplus +extern "C" { +#endif + struct ID; struct View3D; struct ARegion; @@ -224,5 +228,9 @@ int ED_mesh_uv_texture_remove(struct bContext *C, struct Object *ob, struct Mesh int ED_mesh_color_add(struct bContext *C, struct Scene *scene, struct Object *ob, struct Mesh *me, const char *name, int active_set); int ED_mesh_color_remove(struct bContext *C, struct Object *ob, struct Mesh *me); +#ifdef __cplusplus +} +#endif + #endif /* ED_MESH_H */ diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index f243b4cc497..64e72a5e2fa 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -28,6 +28,10 @@ #ifndef ED_OBJECT_H #define ED_OBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + struct Base; struct bConstraint; struct bContext; @@ -141,5 +145,9 @@ int ED_object_modifier_convert(struct ReportList *reports, struct Main *bmain, s int ED_object_modifier_apply(struct ReportList *reports, struct Scene *scene, struct Object *ob, struct ModifierData *md, int mode); int ED_object_modifier_copy(struct ReportList *reports, struct Object *ob, struct ModifierData *md); +#ifdef __cplusplus +} +#endif + #endif /* ED_OBJECT_H */ diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index 8908143946a..6c0b4db221d 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -30,6 +30,10 @@ #ifndef DNA_CUSTOMDATA_TYPES_H #define DNA_CUSTOMDATA_TYPES_H +#ifdef __cplusplus +extern "C" { +#endif + /* descriptor and storage for a custom data layer */ typedef struct CustomDataLayer { int type; /* type of data in layer */ @@ -128,4 +132,8 @@ typedef struct CustomData { #define MAX_MTFACE 8 #define MAX_MCOL 8 +#ifdef __cplusplus +} +#endif + #endif diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h index e9e058cbbd6..19aacaa8108 100644 --- a/source/blender/makesdna/DNA_texture_types.h +++ b/source/blender/makesdna/DNA_texture_types.h @@ -34,6 +34,10 @@ #include "DNA_ID.h" #include "DNA_image_types.h" /* ImageUser */ +#ifdef __cplusplus +extern "C" { +#endif + struct AnimData; struct Ipo; struct PluginTex; @@ -554,5 +558,9 @@ typedef struct TexMapping { #define TEX_VD_SMOKEHEAT 1 #define TEX_VD_SMOKEVEL 2 +#ifdef __cplusplus +} +#endif + #endif diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 52e82eb743d..4e3a957d775 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -35,6 +35,10 @@ #include "DNA_listBase.h" #include "DNA_texture_types.h" /* ColorBand */ +#ifdef __cplusplus +extern "C" { +#endif + /* themes; defines in BIF_resource.h */ struct ColorBand; @@ -558,4 +562,8 @@ extern UserDef U; /* from blenkernel blender.c */ #define TH_OLDSKOOL 3 #define TH_SHADED 4 +#ifdef __cplusplus +} +#endif + #endif diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c index 93b38499673..d6964f5d569 100644 --- a/source/blender/makesrna/intern/rna_screen.c +++ b/source/blender/makesrna/intern/rna_screen.c @@ -44,10 +44,10 @@ EnumPropertyItem region_type_items[] = { {RGN_TYPE_PREVIEW, "PREVIEW", 0, "Preview", ""}, {0, NULL, 0, NULL, NULL}}; -#ifdef RNA_RUNTIME - #include "ED_screen.h" +#ifdef RNA_RUNTIME + #include "WM_api.h" #include "WM_types.h" diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 690d8ad0f75..f103cbe2d4e 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -31,6 +31,10 @@ /* dna-savable wmStructs here */ #include "DNA_windowmanager_types.h" +#ifdef __cplusplus +extern "C" { +#endif + struct bContext; struct IDProperty; struct wmEvent; @@ -338,5 +342,9 @@ void WM_clipboard_text_set(char *buf, int selection); void WM_progress_set(struct wmWindow *win, float progress); void WM_progress_clear(struct wmWindow *win); +#ifdef __cplusplus +} +#endif + #endif /* WM_API_H */ diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 73f1fe8cbd3..0447524255f 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -28,6 +28,10 @@ #ifndef WM_TYPES_H #define WM_TYPES_H +#ifdef __cplusplus +extern "C" { +#endif + struct bContext; struct wmEvent; struct wmWindowManager; @@ -511,5 +515,9 @@ typedef struct RecentFile { } RecentFile; +#ifdef __cplusplus +} +#endif + #endif /* WM_TYPES_H */ -- cgit v1.2.3 From 9f3d203acbc267063f274209b460dc5f059100e6 Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Tue, 5 Oct 2010 00:49:39 +0000 Subject: SVN maintenance. --- source/blender/collada/AnimationImporter.cpp | 2 +- source/blender/collada/AnimationImporter.h | 4 ++-- source/blender/collada/ArmatureImporter.cpp | 4 ++-- source/blender/collada/ArmatureImporter.h | 4 ++-- source/blender/collada/MeshImporter.cpp | 2 +- source/blender/collada/MeshImporter.h | 2 +- source/blender/collada/SkinInfo.cpp | 4 ++-- source/blender/collada/SkinInfo.h | 4 ++-- source/blender/collada/TransformReader.cpp | 4 ++-- source/blender/collada/TransformReader.h | 4 ++-- source/blender/collada/collada_utils.cpp | 2 +- source/blender/collada/collada_utils.h | 2 +- 12 files changed, 19 insertions(+), 19 deletions(-) (limited to 'source/blender') diff --git a/source/blender/collada/AnimationImporter.cpp b/source/blender/collada/AnimationImporter.cpp index 92e863db023..32390fe01eb 100644 --- a/source/blender/collada/AnimationImporter.cpp +++ b/source/blender/collada/AnimationImporter.cpp @@ -1,5 +1,5 @@ /** - * $Id: DocumentImporter.cpp 32235 2010-10-01 19:46:42Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/collada/AnimationImporter.h b/source/blender/collada/AnimationImporter.h index 9854a9d2663..01abac38280 100644 --- a/source/blender/collada/AnimationImporter.h +++ b/source/blender/collada/AnimationImporter.h @@ -1,5 +1,5 @@ /** - * $Id: DocumentImporter.cpp 32235 2010-10-01 19:46:42Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -129,4 +129,4 @@ public: void add_bezt(FCurve *fcu, float fra, float value); }; - #endif \ No newline at end of file + #endif diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp index f931c04aef1..a8ac6d8b768 100644 --- a/source/blender/collada/ArmatureImporter.cpp +++ b/source/blender/collada/ArmatureImporter.cpp @@ -1,5 +1,5 @@ /** - * $Id: DocumentImporter.cpp 32235 2010-10-01 19:46:42Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -582,4 +582,4 @@ bool ArmatureImporter::get_joint_bind_mat(float m[][4], COLLADAFW::Node *joint) } return found; -} \ No newline at end of file +} diff --git a/source/blender/collada/ArmatureImporter.h b/source/blender/collada/ArmatureImporter.h index 64d4669b33c..a857ab67f12 100644 --- a/source/blender/collada/ArmatureImporter.h +++ b/source/blender/collada/ArmatureImporter.h @@ -1,5 +1,5 @@ /** - * $Id: DocumentImporter.cpp 32235 2010-10-01 19:46:42Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -157,4 +157,4 @@ public: bool get_joint_bind_mat(float m[][4], COLLADAFW::Node *joint); }; -#endif \ No newline at end of file +#endif diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp index a210eb3b2e0..da8ae70fdb3 100644 --- a/source/blender/collada/MeshImporter.cpp +++ b/source/blender/collada/MeshImporter.cpp @@ -1,5 +1,5 @@ /** - * $Id: DocumentImporter.cpp 32235 2010-10-01 19:46:42Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/collada/MeshImporter.h b/source/blender/collada/MeshImporter.h index 8c468b01fb6..1fa9ebfbabc 100644 --- a/source/blender/collada/MeshImporter.h +++ b/source/blender/collada/MeshImporter.h @@ -1,5 +1,5 @@ /** - * $Id: DocumentImporter.cpp 32235 2010-10-01 19:46:42Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/collada/SkinInfo.cpp b/source/blender/collada/SkinInfo.cpp index db6a7a62b54..58985d58db3 100644 --- a/source/blender/collada/SkinInfo.cpp +++ b/source/blender/collada/SkinInfo.cpp @@ -1,5 +1,5 @@ /** - * $Id: DocumentImporter.cpp 32235 2010-10-01 19:46:42Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -317,4 +317,4 @@ bool SkinInfo::find_node_in_tree(COLLADAFW::Node *node, COLLADAFW::Node *tree_ro } return false; -} \ No newline at end of file +} diff --git a/source/blender/collada/SkinInfo.h b/source/blender/collada/SkinInfo.h index b7b87494be6..1e31baff2a9 100644 --- a/source/blender/collada/SkinInfo.h +++ b/source/blender/collada/SkinInfo.h @@ -1,5 +1,5 @@ /** - * $Id: DocumentImporter.cpp 32235 2010-10-01 19:46:42Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -130,4 +130,4 @@ public: }; -#endif \ No newline at end of file +#endif diff --git a/source/blender/collada/TransformReader.cpp b/source/blender/collada/TransformReader.cpp index d951bfb6474..814fda58e3c 100644 --- a/source/blender/collada/TransformReader.cpp +++ b/source/blender/collada/TransformReader.cpp @@ -1,5 +1,5 @@ /** - * $Id: DocumentImporter.cpp 32235 2010-10-01 19:46:42Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -122,4 +122,4 @@ void TransformReader::dae_vector3_to_v3(const COLLADABU::Math::Vector3 &v3, floa v[0] = v3.x; v[1] = v3.y; v[2] = v3.z; -} \ No newline at end of file +} diff --git a/source/blender/collada/TransformReader.h b/source/blender/collada/TransformReader.h index fa08df1d4fa..4dff8884a44 100644 --- a/source/blender/collada/TransformReader.h +++ b/source/blender/collada/TransformReader.h @@ -1,5 +1,5 @@ /** - * $Id: DocumentImporter.cpp 32235 2010-10-01 19:46:42Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -67,4 +67,4 @@ public: void dae_vector3_to_v3(const COLLADABU::Math::Vector3 &v3, float v[3]); }; -#endif \ No newline at end of file +#endif diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp index ec0bc91ee0b..0634c910e96 100644 --- a/source/blender/collada/collada_utils.cpp +++ b/source/blender/collada/collada_utils.cpp @@ -1,5 +1,5 @@ /** - * $Id: DocumentImporter.cpp 32235 2010-10-01 19:46:42Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h index dbcbfdafec8..ba5ba7f3cf5 100644 --- a/source/blender/collada/collada_utils.h +++ b/source/blender/collada/collada_utils.h @@ -1,5 +1,5 @@ /** - * $Id: DocumentImporter.cpp 32235 2010-10-01 19:46:42Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * -- cgit v1.2.3 From 4eae531f31382a8632428131a654191eb3947205 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Tue, 5 Oct 2010 06:10:17 +0000 Subject: TextureCoordinateBinding.getName() -> TextureCoordinateBinding.getSemantic(); as per my own patch on OpenCOLLADA issue tracker. --- source/blender/collada/MeshImporter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender') diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp index da8ae70fdb3..34da6c9e897 100644 --- a/source/blender/collada/MeshImporter.cpp +++ b/source/blender/collada/MeshImporter.cpp @@ -700,7 +700,7 @@ MTex *MeshImporter::assign_textures_to_uvlayer(COLLADAFW::TextureCoordinateBindi { const COLLADAFW::TextureMapId texture_index = ctexture.getTextureMapId(); const size_t setindex = ctexture.getSetIndex(); - std::string uvname = ctexture.getName(); + std::string uvname = ctexture.getSemantic(); const CustomData *data = &me->fdata; int layer_index = CustomData_get_layer_index(data, CD_MTFACE); @@ -904,4 +904,4 @@ bool MeshImporter::write_geometry(const COLLADAFW::Geometry* geom) mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); return true; -} +} \ No newline at end of file -- cgit v1.2.3 From a92c232c8b94d926b14785fb95cf8592f7deb1c3 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 5 Oct 2010 07:22:44 +0000 Subject: Fixed own typo in last commit to curve RNA --- source/blender/makesrna/intern/rna_curve.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender') diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index 50c21640554..7983b8f8a7f 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -1373,7 +1373,7 @@ static void rna_def_curve_nurb(BlenderRNA *brna) prop= RNA_def_property(srna, "use_cyclic_v", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flagv", CU_NURB_CYCLIC); RNA_def_property_ui_text(prop, "Cyclic V", "Make this surface a closed loop in the V direction"); - RNA_def_property_update(prop, 0, "rna_Nurb_update_cyclic_u"); + RNA_def_property_update(prop, 0, "rna_Nurb_update_cyclic_v"); /* Note, endpoint and bezier flags should never be on at the same time! */ -- cgit v1.2.3 From 6ca186fc5ac422001559a0c86d3d436163acc849 Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Tue, 5 Oct 2010 09:32:35 +0000 Subject: Fix for [#24107] Hair/General particle glitch- Presets --- source/blender/makesrna/intern/rna_particle.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source/blender') diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 1151215f5f7..7a8165e9aa5 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -325,15 +325,21 @@ static PointerRNA rna_particle_settings_get(PointerRNA *ptr) static void rna_particle_settings_set(PointerRNA *ptr, PointerRNA value) { ParticleSystem *psys= (ParticleSystem*)ptr->data; + int old_type = 0; - if(psys->part) + + if(psys->part) { + old_type = psys->part->type; psys->part->id.us--; + } psys->part = (ParticleSettings *)value.data; if(psys->part) { psys->part->id.us++; psys_check_boid_data(psys); + if(old_type != psys->part->type) + psys->recalc |= PSYS_RECALC_TYPE; } } static void rna_Particle_abspathtime_update(Main *bmain, Scene *scene, PointerRNA *ptr) -- cgit v1.2.3 From a7258c96512d45f2392e13f5d5c8fb6edf651a00 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 5 Oct 2010 11:16:07 +0000 Subject: - fix for crash when drawing a subsurf after a modifier that lost original indices (bevel/screw/decimate) - fix for own mistake used madd_v3_v3fl rather then mul_v3_v3fl, r32241. --- source/blender/blenkernel/intern/subsurf_ccg.c | 4 +++- source/blender/editors/space_view3d/drawmesh.c | 2 +- source/blender/gpu/intern/gpu_draw.c | 10 +++++----- 3 files changed, 9 insertions(+), 7 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index d6486c3ee4d..b0ea5f979ac 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -1619,8 +1619,10 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, if(drawParams) flag = drawParams(tf, mcol, mat_nr); - else + else if(index != ORIGINDEX_NONE) flag= (drawParamsMapped)? drawParamsMapped(userData, index): 1; + else + flag= 1; if (flag == 0) { /* flag 0 == the face is hidden or invisible */ if(tf) tf += gridFaces*gridFaces*numVerts; diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index 372ac976342..53b32dd167c 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -523,7 +523,7 @@ static int draw_em_tf_mapped__set_draw(void *userData, int index) MCol *mcol; int matnr; - if (efa==NULL || efa->h) + if (efa->h) return 0; tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index e8701793e5d..55522ea18b9 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -911,10 +911,10 @@ static void gpu_material_to_fixed(GPUMaterialFixed *smat, const Material *bmat, } } else { - madd_v3_v3fl(smat->diff, &bmat->r, bmat->ref + bmat->emit); + mul_v3_v3fl(smat->diff, &bmat->r, bmat->ref + bmat->emit); smat->diff[3]= 1.0; /* caller may set this to bmat->alpha */ - madd_v3_v3fl(smat->spec, &bmat->specr, bmat->spec); + mul_v3_v3fl(smat->spec, &bmat->specr, bmat->spec); smat->spec[3]= 1.0; /* always 1 */ smat->hard= CLAMPIS(bmat->har, 0, 128); @@ -1043,10 +1043,10 @@ int GPU_enable_material(int nr, void *attribs) memset(&GMS, 0, sizeof(GMS)); - madd_v3_v3fl(diff, &defmaterial.r, defmaterial.ref + defmaterial.emit); + mul_v3_v3fl(diff, &defmaterial.r, defmaterial.ref + defmaterial.emit); diff[3]= 1.0; - madd_v3_v3fl(spec, &defmaterial.specr, defmaterial.spec); + mul_v3_v3fl(spec, &defmaterial.specr, defmaterial.spec); spec[3]= 1.0; glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diff); @@ -1286,7 +1286,7 @@ int GPU_scene_object_lights(Scene *scene, Object *ob, int lay, float viewmat[][4 } /* setup energy */ - madd_v3_v3fl(energy, &la->r, la->energy); + mul_v3_v3fl(energy, &la->r, la->energy); energy[3]= 1.0; glLightfv(GL_LIGHT0+count, GL_DIFFUSE, energy); -- cgit v1.2.3 From 0eeeab515b6b46f907016091b3a89bf5e320c400 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 5 Oct 2010 11:25:34 +0000 Subject: bugfix [#23506] Bevel Modifier display problem This is a more general problem that drawing functions would skip faces when the original index could not be found, screw result for example wasnt visible in editmode too. Fixed by adding a material set argument to DerivedMesh->drawMappedFaces(), this was already being done in some of the other drawing functions. --- source/blender/blenkernel/BKE_DerivedMesh.h | 3 +- source/blender/blenkernel/intern/DerivedMesh.c | 4 +- source/blender/blenkernel/intern/cdderivedmesh.c | 47 ++++++++++++------------ source/blender/blenkernel/intern/subsurf_ccg.c | 21 +++++++---- source/blender/editors/space_view3d/drawmesh.c | 2 +- source/blender/editors/space_view3d/drawobject.c | 22 +++++------ 6 files changed, 54 insertions(+), 45 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 33852a1b923..5b33d9e1c53 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -280,7 +280,8 @@ struct DerivedMesh { void (*drawMappedFaces)(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), - void *userData, int useColors); + void *userData, int useColors, + int (*setMaterial)(int, void *attribs)); /* Draw mapped faces using MTFace * o Drawing options too complicated to enumerate, look at code. diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 01b02653a51..eb5d77bb9b0 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -626,7 +626,9 @@ static void emDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *use func(userData, i, cent, emdm->vertexCos?emdm->faceNos[i]:efa->n); } } -static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors) + +/* note, material function is ignored for now. */ +static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors, int (*setMaterial)(int, void *attribs)) { EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; EditFace *efa; diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index e2ecf21bd62..b9ca7bfafe3 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -777,7 +777,7 @@ static void cdDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tfa cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL); } -static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors) +static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors, int (*setMaterial)(int, void *attribs)) { CDDerivedMesh *cddm = (CDDerivedMesh*) dm; MVert *mv = cddm->mvert; @@ -798,16 +798,16 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us DEBUG_VBO( "Using legacy code. cdDM_drawMappedFaces\n" ); for(i = 0; i < dm->numFaceData; i++, mf++) { int drawSmooth = (mf->flag & ME_SMOOTH); + int draw= 1; - if(index) { - orig = *index++; - if(setDrawOptions && orig == ORIGINDEX_NONE) - { if(nors) nors += 3; continue; } - } - else - orig = i; + orig= (index==NULL) ? i : *index++; + + if(orig == ORIGINDEX_NONE) + draw= setMaterial(mf->mat_nr + 1, NULL); + else if (setDrawOptions != NULL) + draw= setDrawOptions(userData, orig, &drawSmooth); - if(!setDrawOptions || setDrawOptions(userData, orig, &drawSmooth)) { + if(draw) { unsigned char *cp = NULL; if(useColors && mc) @@ -887,22 +887,19 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us for( i = 0; i < tottri; i++ ) { //int actualFace = dm->drawObject->faceRemap[i]; int actualFace = next_actualFace; - int drawSmooth = (mf[actualFace].flag & ME_SMOOTH); + MFace *mface= mf + actualFace; + int drawSmooth= (mface->flag & ME_SMOOTH); int draw = 1; if(i != tottri-1) next_actualFace= dm->drawObject->faceRemap[i+1]; - - if(index) { - orig = index[actualFace]; - if(orig == ORIGINDEX_NONE) - draw = 0; - } - else - orig = actualFace; - - if(draw && !setDrawOptions(userData, orig, &drawSmooth)) - draw = 0; + + orig= (index==NULL) ? actualFace : index[actualFace]; + + if(orig == ORIGINDEX_NONE) + draw= setMaterial(mface->mat_nr + 1, NULL); + else if (setDrawOptions != NULL) + draw= setDrawOptions(userData, orig, &drawSmooth); /* Goal is to draw as long of a contiguous triangle array as possible, so draw when we hit either an @@ -974,8 +971,12 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo else if(setDrawOptions) { orig = (index)? index[a]: a; - if(orig == ORIGINDEX_NONE) - continue; + if(orig == ORIGINDEX_NONE) { + /* since the material is set by setMaterial(), faces with no + * origin can be assumed to be generated by a modifier */ + + /* continue */ + } else if(!setDrawOptions(userData, orig)) continue; } diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index b0ea5f979ac..6323e1e3c79 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -1619,11 +1619,12 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, if(drawParams) flag = drawParams(tf, mcol, mat_nr); - else if(index != ORIGINDEX_NONE) + else if (index != ORIGINDEX_NONE) flag= (drawParamsMapped)? drawParamsMapped(userData, index): 1; else - flag= 1; - + flag= GPU_enable_material(mat_nr, NULL) ? 1:0; + + if (flag == 0) { /* flag 0 == the face is hidden or invisible */ if(tf) tf += gridFaces*gridFaces*numVerts; if(mcol) mcol += gridFaces*gridFaces*numVerts*4; @@ -1763,7 +1764,7 @@ static void ccgDM_drawUVEdges(DerivedMesh *dm) } } -static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors) { +static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors, int (*setMaterial)(int, void *attribs)) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGSubSurf *ss = ccgdm->ss; MCol *mcol= NULL; @@ -1795,10 +1796,14 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *u mcol += gridFaces*gridFaces*numVerts*4; } - if (index!=-1) { - int draw; - draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, index, &drawSmooth); - + { + int draw= 1; + + if(index == ORIGINDEX_NONE) + draw= setMaterial(faceFlags ? faceFlags[origIndex*2 + 1] + 1: 1, NULL); /* XXX, no faceFlags no material */ + else if (setDrawOptions) + draw= setDrawOptions(userData, index, &drawSmooth); + if (draw) { if (draw==2) { glEnable(GL_POLYGON_STIPPLE); diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index 53b32dd167c..7a7462433d7 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -647,7 +647,7 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *o dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, me->edit_mesh); } else if(faceselect) { if(ob->mode & OB_MODE_WEIGHT_PAINT) - dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me, 1); + dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me, 1, GPU_enable_material); else dm->drawMappedFacesTex(dm, draw_tface_mapped__set_draw, me); } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 30b12b96ed5..aba3d04d960 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -1867,7 +1867,7 @@ static void draw_dm_faces_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned data.cols[2] = actCol; data.efa_act = efa_act; - dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, &data, 0); + dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, &data, 0, GPU_enable_material); } static int draw_dm_creases__setDrawOptions(void *userData, int index) @@ -2287,7 +2287,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object glEnable(GL_LIGHTING); glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW); - finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, 0, 0); + finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, 0, 0, GPU_enable_material); glFrontFace(GL_CCW); glDisable(GL_LIGHTING); @@ -2517,7 +2517,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D /* weight paint in solid mode, special case. focus on making the weights clear * rather then the shading, this is also forced in wire view */ GPU_enable_material(0, NULL); - dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me->mface, 1); + dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me->mface, 1, GPU_enable_material); bglPolygonOffset(rv3d->dist, 1.0); glDepthMask(0); // disable write in zbuffer, selected edge wires show better @@ -2599,7 +2599,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D glEnable(GL_LIGHTING); glEnable(GL_COLOR_MATERIAL); - dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me->mface, 1); + dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me->mface, 1, GPU_enable_material); glDisable(GL_COLOR_MATERIAL); glDisable(GL_LIGHTING); @@ -2607,10 +2607,10 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D } else if(ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_TEXTURE_PAINT)) { if(me->mcol) - dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, NULL, 1); + dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, NULL, 1, GPU_enable_material); else { glColor3f(1.0f, 1.0f, 1.0f); - dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, NULL, 0); + dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, NULL, 0, GPU_enable_material); } } else do_draw= 1; @@ -6328,7 +6328,7 @@ static void bbs_mesh_solid_EM(Scene *scene, View3D *v3d, Object *ob, DerivedMesh cpack(0); if (facecol) { - dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, (void*)(intptr_t) 1, 0); + dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, (void*)(intptr_t) 1, 0, GPU_enable_material); if(check_ob_drawface_dot(scene, v3d, ob->dt)) { glPointSize(UI_GetThemeValuef(TH_FACEDOT_SIZE)); @@ -6339,7 +6339,7 @@ static void bbs_mesh_solid_EM(Scene *scene, View3D *v3d, Object *ob, DerivedMesh } } else { - dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, (void*) 0, 0); + dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, (void*) 0, 0, GPU_enable_material); } } @@ -6369,8 +6369,8 @@ static void bbs_mesh_solid(Scene *scene, View3D *v3d, Object *ob) glColor3ub(0, 0, 0); - if(face_sel_mode) dm->drawMappedFaces(dm, bbs_mesh_solid_hide__setDrawOpts, me, 0); - else dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, me, 0); + if(face_sel_mode) dm->drawMappedFaces(dm, bbs_mesh_solid_hide__setDrawOpts, me, 0, GPU_enable_material); + else dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, me, 0, GPU_enable_material); dm->release(dm); } @@ -6477,7 +6477,7 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r GPU_end_object_materials(); } else if(edm) - edm->drawMappedFaces(edm, NULL, NULL, 0); + edm->drawMappedFaces(edm, NULL, NULL, 0, GPU_enable_material); glDisable(GL_LIGHTING); } -- cgit v1.2.3 From 629ddacd48d1cb4256f25620730ab870bbd7eb60 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 5 Oct 2010 11:55:54 +0000 Subject: Fix #24135: Material modification not immediately updated in Outliner Also fixed outliner update when changing active_material_index from Py and when selecting texture from UI --- source/blender/editors/render/render_shading.c | 2 ++ source/blender/editors/space_outliner/outliner.c | 4 +++- source/blender/editors/space_outliner/space_outliner.c | 12 ++++++++++++ source/blender/makesrna/intern/rna_object.c | 14 ++++++++++---- 4 files changed, 27 insertions(+), 5 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index debd13c8d99..71a46a16f98 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -263,6 +263,7 @@ static int material_slot_add_exec(bContext *C, wmOperator *op) object_add_material_slot(ob); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + WM_event_add_notifier(C, NC_OBJECT|ND_OB_SHADING, ob); return OPERATOR_FINISHED; } @@ -290,6 +291,7 @@ static int material_slot_remove_exec(bContext *C, wmOperator *op) object_remove_material_slot(ob); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + WM_event_add_notifier(C, NC_OBJECT|ND_OB_SHADING, ob); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c index aaeab9e7843..b876aa11ab5 100644 --- a/source/blender/editors/space_outliner/outliner.c +++ b/source/blender/editors/space_outliner/outliner.c @@ -2050,7 +2050,9 @@ static int tree_element_active_texture(bContext *C, Scene *scene, SpaceOops *soo } } - WM_event_add_notifier(C, NC_TEXTURE, NULL); + if(set) + WM_event_add_notifier(C, NC_TEXTURE, NULL); + return 0; } diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c index d91c8caa14c..f0f9ac945ef 100644 --- a/source/blender/editors/space_outliner/space_outliner.c +++ b/source/blender/editors/space_outliner/space_outliner.c @@ -116,6 +116,7 @@ static void outliner_main_area_listener(ARegion *ar, wmNotifier *wmn) case ND_BONE_ACTIVE: case ND_BONE_SELECT: case ND_PARENT: + case ND_OB_SHADING: ED_region_tag_redraw(ar); break; case ND_CONSTRAINT: @@ -150,6 +151,17 @@ static void outliner_main_area_listener(ARegion *ar, wmNotifier *wmn) if(wmn->action == NA_RENAME) ED_region_tag_redraw(ar); break; + case NC_MATERIAL: + switch(wmn->data) { + case ND_SHADING: + case ND_SHADING_DRAW: + ED_region_tag_redraw(ar); + break; + } + break; + case NC_TEXTURE: + ED_region_tag_redraw(ar); + break; } } diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 3f07d953e0b..e74bec566d5 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -769,6 +769,12 @@ static void rna_MaterialSlot_name_get(PointerRNA *ptr, char *str) strcpy(str, ""); } +static void rna_MaterialSlot_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + rna_Object_internal_update(bmain, scene, ptr); + WM_main_add_notifier(NC_OBJECT|ND_OB_SHADING, ptr->id.data); +} + /* why does this have to be so complicated?, can't all this crap be * moved to in BGE conversion function? - Campbell * * @@ -1143,13 +1149,13 @@ static void rna_def_material_slot(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_pointer_funcs(prop, "rna_MaterialSlot_material_get", "rna_MaterialSlot_material_set", NULL, NULL); RNA_def_property_ui_text(prop, "Material", "Material datablock used by this material slot"); - RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Object_internal_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_MaterialSlot_update"); prop= RNA_def_property(srna, "link", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, link_items); RNA_def_property_enum_funcs(prop, "rna_MaterialSlot_link_get", "rna_MaterialSlot_link_set", NULL); RNA_def_property_ui_text(prop, "Link", "Link material to object or the object's data"); - RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Object_internal_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_MaterialSlot_update"); prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_string_funcs(prop, "rna_MaterialSlot_name_get", "rna_MaterialSlot_name_length", NULL); @@ -1739,14 +1745,14 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_pointer_funcs(prop, "rna_Object_active_material_get", "rna_Object_active_material_set", NULL, NULL); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Active Material", "Active material being displayed"); - RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Object_internal_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_MaterialSlot_update"); prop= RNA_def_property(srna, "active_material_index", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "actcol"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_int_funcs(prop, "rna_Object_active_material_index_get", "rna_Object_active_material_index_set", "rna_Object_active_material_index_range"); RNA_def_property_ui_text(prop, "Active Material Index", "Index of active material slot"); - RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL); + RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); /* transform */ prop= RNA_def_property(srna, "location", PROP_FLOAT, PROP_TRANSLATION); -- cgit v1.2.3 From 1bf56930ac18c7ae6c37079fb25446108e1e7309 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 5 Oct 2010 13:15:58 +0000 Subject: bugfix [#24122] Shift-C doesn't work in "Camera View" also fixed some glitches with smoothview. --- source/blender/editors/space_view3d/view3d_edit.c | 30 ++++++--------------- source/blender/editors/space_view3d/view3d_view.c | 32 +++++++++++++---------- 2 files changed, 26 insertions(+), 36 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 06d93f01e02..4cac0e297d1 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -1274,7 +1274,7 @@ void VIEW3D_OT_zoom(wmOperatorType *ot) RNA_def_int(ot->srna, "my", 0, 0, INT_MAX, "Zoom Position Y", "", 0, INT_MAX); } -static int viewhome_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2.4x */ +static int view3d_all_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2.4x */ { ARegion *ar= CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); @@ -1289,12 +1289,11 @@ static int viewhome_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2. int ok= 1, onedone=0; if(center) { - min[0]= min[1]= min[2]= 0.0f; - max[0]= max[1]= max[2]= 0.0f; - /* in 2.4x this also move the cursor to (0, 0, 0) (with shift+c). */ curs= give_cursor(scene, v3d); - curs[0]= curs[1]= curs[2]= 0.0; + zero_v3(min); + zero_v3(max); + zero_v3(curs); } else { INIT_MINMAX(min, max); @@ -1318,9 +1317,7 @@ static int viewhome_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2. return OPERATOR_FINISHED; } - afm[0]= (max[0]-min[0]); - afm[1]= (max[1]-min[1]); - afm[2]= (max[2]-min[2]); + sub_v3_v3v3(afm, max, min); size= 0.7f*MAX3(afm[0], afm[1], afm[2]); if(size==0.0) ok= 0; @@ -1342,7 +1339,7 @@ static int viewhome_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2. if (rv3d->persp==RV3D_CAMOB) { rv3d->persp= RV3D_PERSP; - smooth_view(C, NULL, v3d->camera, new_ofs, NULL, &new_dist, NULL); + smooth_view(C, v3d->camera, NULL, new_ofs, NULL, &new_dist, NULL); } else { smooth_view(C, NULL, NULL, new_ofs, NULL, &new_dist, NULL); @@ -1358,17 +1355,6 @@ static int viewhome_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2. return OPERATOR_FINISHED; } -static int viewhome_poll(bContext *C) -{ - if(ED_operator_view3d_active(C)) { - RegionView3D *rv3d= CTX_wm_region_view3d(C); //XXX, when accessed from a header menu this doesnt work! - if(rv3d && rv3d->persp!=RV3D_CAMOB) { - return 1; - } - } - - return 0; -} void VIEW3D_OT_view_all(wmOperatorType *ot) { @@ -1378,8 +1364,8 @@ void VIEW3D_OT_view_all(wmOperatorType *ot) ot->idname= "VIEW3D_OT_view_all"; /* api callbacks */ - ot->exec= viewhome_exec; - ot->poll= viewhome_poll; + ot->exec= view3d_all_exec; + ot->poll= ED_operator_view3d_active; /* flags */ ot->flag= 0; diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index d66144b2c30..860f9f461c4 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -205,7 +205,7 @@ void smooth_view(bContext *C, Object *oldcamera, Object *camera, float *ofs, flo if(quat) copy_qt_qt(sms.new_quat, quat); if(dist) sms.new_dist= *dist; if(lens) sms.new_lens= *lens; - + if (camera) { view3d_settings_from_ob(camera, sms.new_ofs, sms.new_quat, &sms.new_dist, &sms.new_lens); sms.to_camera= 1; /* restore view3d values in end */ @@ -214,15 +214,15 @@ void smooth_view(bContext *C, Object *oldcamera, Object *camera, float *ofs, flo if (C && U.smooth_viewtx) { int changed = 0; /* zero means no difference */ - if (sms.new_dist != rv3d->dist) + if (oldcamera != camera) changed = 1; - if (sms.new_lens != v3d->lens) + else if (sms.new_dist != rv3d->dist) changed = 1; - - if (!equals_v3v3(sms.new_ofs, rv3d->ofs)) + else if (sms.new_lens != v3d->lens) changed = 1; - - if (!equals_v4v4(sms.new_quat, rv3d->viewquat)) + else if (!equals_v3v3(sms.new_ofs, rv3d->ofs)) + changed = 1; + else if (!equals_v4v4(sms.new_quat, rv3d->viewquat)) changed = 1; /* The new view is different from the old one @@ -449,17 +449,21 @@ static int view3d_setobjectascamera_exec(bContext *C, wmOperator *op) View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d= CTX_wm_region_view3d(C); Scene *scene= CTX_data_scene(C); - - if(BASACT) { + Object *ob = CTX_data_active_object(C); + + if(ob) { + Object *camera_old= (rv3d->persp == RV3D_CAMOB && scene->camera) ? scene->camera : NULL; rv3d->persp= RV3D_CAMOB; - v3d->camera= OBACT; + v3d->camera= ob; if(v3d->scenelock) - scene->camera= OBACT; - smooth_view(C, NULL, v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, &v3d->lens); + scene->camera= ob; + + if(camera_old != ob) /* unlikely but looks like a glitch when set to the same */ + smooth_view(C, camera_old, v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, &v3d->lens); + + WM_event_add_notifier(C, NC_SCENE|ND_RENDER_OPTIONS|NC_OBJECT|ND_DRAW, CTX_data_scene(C)); } - WM_event_add_notifier(C, NC_SCENE|ND_RENDER_OPTIONS|NC_OBJECT|ND_DRAW, CTX_data_scene(C)); - return OPERATOR_FINISHED; } -- cgit v1.2.3 From e1878f7142acb96c8b9cce4fa0557419896511e0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 5 Oct 2010 15:29:06 +0000 Subject: patch [#24146] UV layout selection menu in UV editor ala CTRL+TAB in edit mode --- source/blender/editors/mesh/mesh_ops.c | 2 +- source/blender/editors/uvedit/uvedit_ops.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'source/blender') diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 9e071aa4a21..fa055a385f3 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -251,7 +251,7 @@ void ED_keymap_mesh(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "MESH_OT_select_similar", GKEY, KM_PRESS, KM_SHIFT, 0); /* selection mode */ - WM_keymap_add_menu(keymap, "VIEW3D_MT_edit_mesh_selection_mode", TABKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_menu(keymap, "VIEW3D_MT_edit_mesh_select_mode", TABKEY, KM_PRESS, KM_CTRL, 0); /* hide */ WM_keymap_add_item(keymap, "MESH_OT_hide", HKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 565bad987e3..5c4564f1946 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -3239,6 +3239,7 @@ void ED_keymap_uvedit(wmKeyConfig *keyconf) /* menus */ WM_keymap_add_menu(keymap, "IMAGE_MT_uvs_snap", SKEY, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_menu(keymap, "IMAGE_MT_uvs_select_mode", TABKEY, KM_PRESS, KM_CTRL, 0); ED_object_generic_keymap(keyconf, keymap, 2); -- cgit v1.2.3 From 1e0d2d4700bb1a314e6771aa6404433b8c5a5d68 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 5 Oct 2010 15:44:58 +0000 Subject: patch [#24125] Fix for Slider Widget (UI) from Alexander Kuznetsov (alexk) --- source/blender/editors/interface/interface_widgets.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index b892ce1ca6d..134ab70e4ca 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -284,8 +284,10 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl float facxi= (maxxi!=minxi) ? 1.0f/(maxxi-minxi) : 0.0f; /* for uv, can divide by zero */ float facyi= (maxyi!=minyi) ? 1.0f/(maxyi-minyi) : 0.0f; int a, tot= 0, minsize; + const int hnum= ((roundboxalign & (1|2))==(1|2) || (roundboxalign & (4|8))==(4|8)) ? 1 : 2; + const int vnum= ((roundboxalign & (1|8))==(1|8) || (roundboxalign & (2|4))==(2|4)) ? 1 : 2; - minsize= MIN2(rect->xmax-rect->xmin, rect->ymax-rect->ymin); + minsize= MIN2((rect->xmax-rect->xmin)*hnum, (rect->ymax-rect->ymin)*vnum); if(2.0f*rad > minsize) rad= 0.5f*minsize; @@ -2219,7 +2221,7 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s uiWidgetBase wtb, wtb1; rcti rect1; double value; - float offs, fac; + float offs, toffs, fac; char outline[3]; widget_init(&wtb); @@ -2229,6 +2231,7 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s /* fully rounded */ offs= 0.5f*(rect->ymax - rect->ymin); + toffs = offs*0.75f; round_box_edges(&wtb, roundboxalign, rect, offs); wtb.outline= 0; @@ -2274,8 +2277,8 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s widgetbase_draw(&wtb, wcol); /* text space */ - rect->xmin += offs*0.75f; - rect->xmax -= offs*0.75f; + rect->xmin += toffs; + rect->xmax -= toffs; } /* I think 3 is sufficient border to indicate keyed status */ -- cgit v1.2.3 From 458de52151994854cd3fec191fe1761bca2c88d0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 5 Oct 2010 18:35:02 +0000 Subject: bugfix [#24148] unable to get keyboard mappings to work in the text window this exposes another problem: RNA_property_is_set cant be used on properties set from a keymap, they are always set. for now check for string length. --- source/blender/editors/space_console/console_ops.c | 8 +++++++- source/blender/editors/space_text/text_ops.c | 19 ++++++++++--------- 2 files changed, 17 insertions(+), 10 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c index 8ececa22163..3f04d0e4293 100644 --- a/source/blender/editors/space_console/console_ops.c +++ b/source/blender/editors/space_console/console_ops.c @@ -403,8 +403,14 @@ static int insert_exec(bContext *C, wmOperator *op) static int insert_invoke(bContext *C, wmOperator *op, wmEvent *event) { - if(!RNA_property_is_set(op->ptr, "text")) { + // if(!RNA_property_is_set(op->ptr, "text")) { /* always set from keymap XXX */ + if(!RNA_string_length(op->ptr, "text")) { char str[2] = {event->ascii, '\0'}; + + /* if alt/ctrl/super are pressed pass through */ + if(event->alt || event->ctrl || event->oskey) + return OPERATOR_PASS_THROUGH; + RNA_string_set(op->ptr, "text", str); } return insert_exec(C, op); diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index ed70f31f970..e3bf390dba8 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -2317,18 +2317,19 @@ static int insert_exec(bContext *C, wmOperator *op) static int insert_invoke(bContext *C, wmOperator *op, wmEvent *event) { - char str[2]; int ret; - /* XXX old code from winqreadtextspace, is it still needed somewhere? */ - /* smartass code to prevent the CTRL/ALT events below from not working! */ - /*if(qual & (LR_ALTKEY|LR_CTRLKEY)) - if(!ispunct(ascii)) - ascii= 0;*/ - str[0]= event->ascii; - str[1]= '\0'; + // if(!RNA_property_is_set(op->ptr, "text")) { /* always set from keymap XXX */ + if(!RNA_string_length(op->ptr, "text")) { + char str[2] = {event->ascii, '\0'}; + + /* if alt/ctrl/super are pressed pass through */ + if(event->alt || event->ctrl || event->oskey) + return OPERATOR_PASS_THROUGH; + + RNA_string_set(op->ptr, "text", str); + } - RNA_string_set(op->ptr, "text", str); ret = insert_exec(C, op); /* run the script while editing, evil but useful */ -- cgit v1.2.3 From 568cb066162b13983c8454b9d20ec010b2a1251d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 5 Oct 2010 19:10:15 +0000 Subject: rename Command key to OSKey, Window manager already called it the OSKey but internally it was mixed. --- source/blender/editors/space_outliner/outliner.c | 2 +- source/blender/editors/space_text/text_python.c | 2 +- source/blender/editors/transform/transform.c | 2 +- source/blender/makesrna/intern/rna_wm.c | 2 +- source/blender/windowmanager/intern/wm_event_system.c | 4 ++-- source/blender/windowmanager/intern/wm_window.c | 4 ++-- source/blender/windowmanager/wm_event_types.h | 4 ++-- 7 files changed, 10 insertions(+), 10 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c index b876aa11ab5..c9aac8502c4 100644 --- a/source/blender/editors/space_outliner/outliner.c +++ b/source/blender/editors/space_outliner/outliner.c @@ -5545,7 +5545,7 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo uiDefButS(block, OPTION, 0, "Shift", xstart, (int)te->ys+1, butw3+5, OL_H-1, &kmi->shift, 0, 0, 0, 0, "Modifier"); xstart+= butw3+5; uiDefButS(block, OPTION, 0, "Ctrl", xstart, (int)te->ys+1, butw3, OL_H-1, &kmi->ctrl, 0, 0, 0, 0, "Modifier"); xstart+= butw3; uiDefButS(block, OPTION, 0, "Alt", xstart, (int)te->ys+1, butw3, OL_H-1, &kmi->alt, 0, 0, 0, 0, "Modifier"); xstart+= butw3; - uiDefButS(block, OPTION, 0, "Cmd", xstart, (int)te->ys+1, butw3, OL_H-1, &kmi->oskey, 0, 0, 0, 0, "Modifier"); xstart+= butw3; + uiDefButS(block, OPTION, 0, "OS", xstart, (int)te->ys+1, butw3, OL_H-1, &kmi->oskey, 0, 0, 0, 0, "Modifier"); xstart+= butw3; xstart+= 5; uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys+1, butw3, OL_H-1, &kmi->keymodifier, "Key Modifier code"); xstart+= butw3+5; diff --git a/source/blender/editors/space_text/text_python.c b/source/blender/editors/space_text/text_python.c index aee1a7ecfd6..9be554924c9 100644 --- a/source/blender/editors/space_text/text_python.c +++ b/source/blender/editors/space_text/text_python.c @@ -182,7 +182,7 @@ static void confirm_suggestion(Text *text, int skipleft) #define LR_SHIFTKEY 0 #define LR_ALTKEY 0 #define LR_CTRLKEY 0 -#define LR_COMMANDKEY 0 +#define LR_OSKEY 0 // XXX static int doc_scroll= 0; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index a6fcfb04982..1778e648e20 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1534,7 +1534,7 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int if ((ELEM(kmi->type, LEFTCTRLKEY, RIGHTCTRLKEY) && event->ctrl) || (ELEM(kmi->type, LEFTSHIFTKEY, RIGHTSHIFTKEY) && event->shift) || (ELEM(kmi->type, LEFTALTKEY, RIGHTALTKEY) && event->alt) || - (kmi->type == COMMANDKEY && event->oskey)) { + (kmi->type == OSKEY && event->oskey)) { t->modifiers |= MOD_SNAP_INVERT; } break; diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index 62d0c99f6c5..7e54a3b14fa 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -175,7 +175,7 @@ EnumPropertyItem event_type_items[] = { {RIGHTCTRLKEY, "RIGHT_CTRL", 0, "Right Ctrl", ""}, {RIGHTSHIFTKEY, "RIGHT_SHIFT", 0, "Right Shift", ""}, {0, "", 0, NULL, NULL}, - {COMMANDKEY, "COMMAND", 0, "Command", ""}, + {OSKEY, "OSKEY", 0, "OS Key", ""}, {0, "", 0, NULL, NULL}, {ESCKEY, "ESC", 0, "Esc", ""}, {TABKEY, "TAB", 0, "Tab", ""}, diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 590d28012f9..334bc79b96a 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -2067,7 +2067,7 @@ static int convert_key(GHOST_TKey key) case GHOST_kKeyRightShift: return RIGHTSHIFTKEY; case GHOST_kKeyLeftControl: return LEFTCTRLKEY; case GHOST_kKeyRightControl: return RIGHTCTRLKEY; - case GHOST_kKeyCommand: return COMMANDKEY; + case GHOST_kKeyOS: return OSKEY; case GHOST_kKeyLeftAlt: return LEFTALTKEY; case GHOST_kKeyRightAlt: return RIGHTALTKEY; @@ -2324,7 +2324,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int t if(event.val==KM_PRESS && (evt->ctrl || evt->shift || evt->oskey)) event.alt= evt->alt = 3; // define? } - else if (event.type==COMMANDKEY) { + else if (event.type==OSKEY) { event.oskey= evt->oskey= (event.val==KM_PRESS); if(event.val==KM_PRESS && (evt->ctrl || evt->alt || evt->shift)) event.oskey= evt->oskey = 3; // define? diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 328c3e80259..d9d7abd3a68 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -528,7 +528,7 @@ static int query_qual(char qual) left= GHOST_kModifierKeyLeftControl; right= GHOST_kModifierKeyRightControl; } else if (qual=='C') { - left= right= GHOST_kModifierKeyCommand; + left= right= GHOST_kModifierKeyOS; } else { left= GHOST_kModifierKeyLeftAlt; right= GHOST_kModifierKeyRightAlt; @@ -613,7 +613,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private) wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, time, &kdata); } if (win->eventstate->oskey && !query_qual('C')) { - kdata.key= GHOST_kKeyCommand; + kdata.key= GHOST_kKeyOS; wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, time, &kdata); } /* keymodifier zero, it hangs on hotkeys that open windows otherwise */ diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h index e4b56080b03..efc31f6f7c3 100644 --- a/source/blender/windowmanager/wm_event_types.h +++ b/source/blender/windowmanager/wm_event_types.h @@ -204,7 +204,7 @@ #define ENDKEY 170 #define UNKNOWNKEY 171 -#define COMMANDKEY 172 +#define OSKEY 172 #define GRLESSKEY 173 /* for event checks */ @@ -215,7 +215,7 @@ #define ISKEYBOARD(event) (event >=' ' && event <=320) /* test whether the event is a modifier key */ -#define ISKEYMODIFIER(event) ((event >= LEFTCTRLKEY && event <= LEFTSHIFTKEY) || event == COMMANDKEY) +#define ISKEYMODIFIER(event) ((event >= LEFTCTRLKEY && event <= LEFTSHIFTKEY) || event == OSKEY) /* test whether the event is a mouse button */ #define ISMOUSE(event) (event >= LEFTMOUSE && event <= MOUSEROTATE) -- cgit v1.2.3 From 8408997c84d6c4a8b47808422ed73d7d754ff509 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 5 Oct 2010 21:22:33 +0000 Subject: remove some unused code and reduced the scope if some vars (no functional change). --- source/blender/blenkernel/intern/font.c | 8 ++++---- source/blender/blenkernel/intern/idprop.c | 9 ++------- source/blender/blenkernel/intern/image.c | 10 ++++++---- source/blender/blenkernel/intern/unit.c | 3 +-- source/blender/python/intern/bpy_rna.c | 3 +-- 5 files changed, 14 insertions(+), 19 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index 47627d09b97..131b16b319e 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -514,11 +514,12 @@ static void buildchar(Curve *cu, unsigned long character, CharInfo *info, float float *fp, fsize, shear, x, si, co; VFontData *vfd = NULL; VChar *che = NULL; - int i, sel=0; + int i; vfd= vfont_get_data(which_vfont(cu, info)); if (!vfd) return; + /* if (cu->selend < cu->selstart) { if ((charidx >= (cu->selend)) && (charidx <= (cu->selstart-2))) sel= 1; @@ -527,6 +528,7 @@ static void buildchar(Curve *cu, unsigned long character, CharInfo *info, float if ((charidx >= (cu->selstart-1)) && (charidx <= (cu->selend-1))) sel= 1; } + */ /* make a copy at distance ofsx,ofsy with shear*/ fsize= cu->fsize; @@ -1148,14 +1150,12 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode) if(mode == FO_EDIT) { /* make nurbdata */ - unsigned long cha; - freeNurblist(&cu->nurb); ct= chartransdata; if (cu->sepchar==0) { for (i= 0; imat_nr > (ob->totcol)) { /* printf("Error: Illegal material index (%d) in text object, setting to 0\n", info->mat_nr); */ diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c index a0df73d6c42..639e2062f83 100644 --- a/source/blender/blenkernel/intern/idprop.c +++ b/source/blender/blenkernel/intern/idprop.c @@ -421,9 +421,7 @@ void IDP_SyncGroupValues(IDProperty *dest, IDProperty *src) IDProperty *loop, *prop; for (prop=src->data.group.first; prop; prop=prop->next) { for (loop=dest->data.group.first; loop; loop=loop->next) { - if (BSTR_EQ(loop->name, prop->name)) { - int copy_done= 0; - + if (strcmp(loop->name, prop->name)==0) { if(prop->type==loop->type) { switch (prop->type) { @@ -431,11 +429,9 @@ void IDP_SyncGroupValues(IDProperty *dest, IDProperty *src) case IDP_FLOAT: case IDP_DOUBLE: loop->data= prop->data; - copy_done= 1; break; case IDP_GROUP: IDP_SyncGroupValues(loop, prop); - copy_done= 1; break; default: { @@ -702,7 +698,6 @@ IDProperty *IDP_New(int type, IDPropertyTemplate val, const char *name) case IDP_STRING: { char *st = val.str; - int stlen; prop = MEM_callocN(sizeof(IDProperty), "IDProperty string"); if (st == NULL) { @@ -710,7 +705,7 @@ IDProperty *IDP_New(int type, IDPropertyTemplate val, const char *name) prop->totallen = DEFAULT_ALLOC_FOR_NULL_STRINGS; prop->len = 1; /*NULL string, has len of 1 to account for null byte.*/ } else { - stlen = strlen(st) + 1; + int stlen = strlen(st) + 1; prop->data.pointer = MEM_callocN(stlen, "id property string 2"); prop->len = prop->totallen = stlen; strcpy(prop->data.pointer, st); diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index cb2261932ce..6dd1d4280ec 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -596,7 +596,7 @@ void BKE_image_free_all_textures(void) { Tex *tex; Image *ima; - unsigned int totsize= 0; + /* unsigned int totsize= 0; */ for(ima= G.main->image.first; ima; ima= ima->id.next) ima->id.flag &= ~LIB_DOIT; @@ -607,13 +607,14 @@ void BKE_image_free_all_textures(void) for(ima= G.main->image.first; ima; ima= ima->id.next) { if(ima->ibufs.first && (ima->id.flag & LIB_DOIT)) { + /* ImBuf *ibuf; for(ibuf= ima->ibufs.first; ibuf; ibuf= ibuf->next) { if(ibuf->mipmap[0]) totsize+= 1.33*ibuf->x*ibuf->y*4; else totsize+= ibuf->x*ibuf->y*4; - } + } */ image_free_buffers(ima); } } @@ -2183,7 +2184,7 @@ ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser) void BKE_image_user_calc_frame(ImageUser *iuser, int cfra, int fieldnr) { - int imanr, len; + int len; /* here (+fie_ima/2-1) makes sure that division happens correctly */ len= (iuser->fie_ima*iuser->frames)/2; @@ -2192,8 +2193,9 @@ void BKE_image_user_calc_frame(ImageUser *iuser, int cfra, int fieldnr) iuser->framenr= 0; } else { + int imanr; cfra= cfra - iuser->sfra+1; - + /* cyclic */ if(iuser->cycl) { cfra= ( (cfra) % len ); diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c index 3d984c7e877..25aab77ba9b 100644 --- a/source/blender/blenkernel/intern/unit.c +++ b/source/blender/blenkernel/intern/unit.c @@ -398,7 +398,6 @@ void bUnit_AsString(char *str, int len_max, double value, int prec, int system, /* split output makes sense only for length, mass and time */ if(split && (type==B_UNIT_LENGTH || type==B_UNIT_MASS || type==B_UNIT_TIME)) { - int i; bUnitDef *unit_a, *unit_b; double value_a, value_b; @@ -406,7 +405,7 @@ void bUnit_AsString(char *str, int len_max, double value, int prec, int system, /* check the 2 is a smaller unit */ if(unit_b > unit_a) { - i= unit_as_string(str, len_max, value_a, prec, usys, unit_a, '\0'); + int i= unit_as_string(str, len_max, value_a, prec, usys, unit_a, '\0'); /* is there enough space for at least 1 char of the next unit? */ if(i+2 < len_max) { diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 93106d5400f..166213fa07c 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -3459,10 +3459,9 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, ParameterList *parms, PropertyRNA * PyObject *ret; int type = RNA_property_type(prop); int flag = RNA_property_flag(prop); - int a; if(RNA_property_array_check(ptr, prop)) { - int len; + int a, len; if (flag & PROP_DYNAMIC) { ParameterDynAlloc *data_alloc= data; -- cgit v1.2.3 From eef0ffe9be45fce28436f0be0abdbea6243675ed Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Tue, 5 Oct 2010 22:32:29 +0000 Subject: Unhide confirm on release property (otherwise, it's not easily modifiable in the keymap editor). --- source/blender/editors/transform/transform_ops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 0187a3b3567..95e167053ec 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -445,9 +445,9 @@ void Transform_Properties(struct wmOperatorType *ot, int flags) } } - // Add confirm method all the time. At the end because it's not really that important and should be hidden + // Add confirm method all the time. At the end because it's not really that important and should be hidden only in log, not in keymap edit prop = RNA_def_boolean(ot->srna, "release_confirm", 0, "Confirm on Release", "Always confirm operation when releasing button"); - RNA_def_property_flag(prop, PROP_HIDDEN); + //RNA_def_property_flag(prop, PROP_HIDDEN); } void TRANSFORM_OT_translate(struct wmOperatorType *ot) -- cgit v1.2.3 From fdadab10062cd9fbef6a6585fd19f344280a9d5b Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Wed, 6 Oct 2010 07:13:42 +0000 Subject: COLLADA exporter: split camera and light export into own files. --- source/blender/collada/CameraExporter.cpp | 86 ++++++++ source/blender/collada/CameraExporter.h | 43 ++++ source/blender/collada/DocumentExporter.cpp | 296 +--------------------------- source/blender/collada/LightExporter.cpp | 106 ++++++++++ source/blender/collada/LightExporter.h | 43 ++++ source/blender/collada/collada_internal.cpp | 240 ++++++++++++++++++++++ source/blender/collada/collada_internal.h | 74 +++---- 7 files changed, 554 insertions(+), 334 deletions(-) create mode 100644 source/blender/collada/CameraExporter.cpp create mode 100644 source/blender/collada/CameraExporter.h create mode 100644 source/blender/collada/LightExporter.cpp create mode 100644 source/blender/collada/LightExporter.h create mode 100644 source/blender/collada/collada_internal.cpp (limited to 'source/blender') diff --git a/source/blender/collada/CameraExporter.cpp b/source/blender/collada/CameraExporter.cpp new file mode 100644 index 00000000000..b4ccfd5d6d1 --- /dev/null +++ b/source/blender/collada/CameraExporter.cpp @@ -0,0 +1,86 @@ +/** + * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed, + * Nathan Letwory + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include + +#include "COLLADASWCamera.h" +#include "COLLADASWCameraOptic.h" + +#include "DNA_camera_types.h" + +#include "CameraExporter.h" + +#include "collada_internal.h" + +CamerasExporter::CamerasExporter(COLLADASW::StreamWriter *sw): COLLADASW::LibraryCameras(sw){} + +template +void forEachCameraObjectInScene(Scene *sce, Functor &f) +{ + Base *base= (Base*) sce->base.first; + while(base) { + Object *ob = base->object; + + if (ob->type == OB_CAMERA && ob->data) { + f(ob, sce); + } + base= base->next; + } +} + +void CamerasExporter::exportCameras(Scene *sce) +{ + openLibrary(); + + forEachCameraObjectInScene(sce, *this); + + closeLibrary(); +} +void CamerasExporter::operator()(Object *ob, Scene *sce) +{ + // TODO: shiftx, shifty, YF_dofdist + Camera *cam = (Camera*)ob->data; + std::string cam_id(get_camera_id(ob)); + std::string cam_name(id_name(cam)); + + if (cam->type == CAM_PERSP) { + COLLADASW::PerspectiveOptic persp(mSW); + persp.setXFov(lens_to_angle(cam->lens)*(180.0f/M_PI)); + persp.setAspectRatio(1.0); + persp.setZFar(cam->clipend); + persp.setZNear(cam->clipsta); + COLLADASW::Camera ccam(mSW, &persp, cam_id, cam_name); + addCamera(ccam); + } + else { + COLLADASW::OrthographicOptic ortho(mSW); + ortho.setXMag(cam->ortho_scale); + ortho.setAspectRatio(1.0); + ortho.setZFar(cam->clipend); + ortho.setZNear(cam->clipsta); + COLLADASW::Camera ccam(mSW, &ortho, cam_id, cam_name); + addCamera(ccam); + } +} diff --git a/source/blender/collada/CameraExporter.h b/source/blender/collada/CameraExporter.h new file mode 100644 index 00000000000..a4605b99f52 --- /dev/null +++ b/source/blender/collada/CameraExporter.h @@ -0,0 +1,43 @@ +/** + * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed, + * Nathan Letwory + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __CAMERAEXPORTER_H__ +#define __CAMERAEXPORTER_H__ + +#include "COLLADASWStreamWriter.h" +#include "COLLADASWLibraryCameras.h" + +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +class CamerasExporter: COLLADASW::LibraryCameras +{ +public: + CamerasExporter(COLLADASW::StreamWriter *sw); + void exportCameras(Scene *sce); + void operator()(Object *ob, Scene *sce); +}; + +#endif diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp index c13e089fa4a..661f31f5210 100644 --- a/source/blender/collada/DocumentExporter.cpp +++ b/source/blender/collada/DocumentExporter.cpp @@ -95,11 +95,11 @@ extern char build_rev[]; #include "COLLADASWTexture.h" #include "COLLADASWLibraryMaterials.h" #include "COLLADASWBindMaterial.h" -#include "COLLADASWLibraryCameras.h" +//#include "COLLADASWLibraryCameras.h" #include "COLLADASWLibraryLights.h" #include "COLLADASWInstanceCamera.h" #include "COLLADASWInstanceLight.h" -#include "COLLADASWCameraOptic.h" +//#include "COLLADASWCameraOptic.h" #include "COLLADASWConstants.h" #include "COLLADASWLibraryControllers.h" #include "COLLADASWInstanceController.h" @@ -108,6 +108,9 @@ extern char build_rev[]; #include "collada_internal.h" #include "DocumentExporter.h" +#include "CameraExporter.h" +#include "LightExporter.h" + #include #include // std::find @@ -128,161 +131,6 @@ char *CustomData_get_active_layer_name(const CustomData *data, int type) return data->layers[layer_index].name; } -/** -Translation map. -Used to translate every COLLADA id to a valid id, no matter what "wrong" letters may be -included. Look at the IDREF XSD declaration for more. -Follows strictly the COLLADA XSD declaration which explicitly allows non-english chars, -like special chars (e.g. micro sign), umlauts and so on. -The COLLADA spec also allows additional chars for member access ('.'), these -must obviously be removed too, otherwise they would be heavily misinterpreted. -*/ -const unsigned char translate_start_name_map[256] = { -95, 95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -65, 66, 67, 68, 69, 70, 71, 72, -73, 74, 75, 76, 77, 78, 79, 80, -81, 82, 83, 84, 85, 86, 87, 88, -89, 90, 95, 95, 95, 95, 95, 95, -97, 98, 99, 100, 101, 102, 103, 104, -105, 106, 107, 108, 109, 110, 111, 112, -113, 114, 115, 116, 117, 118, 119, 120, -121, 122, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 192, -193, 194, 195, 196, 197, 198, 199, 200, -201, 202, 203, 204, 205, 206, 207, 208, -209, 210, 211, 212, 213, 214, 95, 216, -217, 218, 219, 220, 221, 222, 223, 224, -225, 226, 227, 228, 229, 230, 231, 232, -233, 234, 235, 236, 237, 238, 239, 240, -241, 242, 243, 244, 245, 246, 95, 248, -249, 250, 251, 252, 253, 254, 255}; - -const unsigned char translate_name_map[256] = { -95, 95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 45, 95, 95, 48, -49, 50, 51, 52, 53, 54, 55, 56, -57, 95, 95, 95, 95, 95, 95, 95, -65, 66, 67, 68, 69, 70, 71, 72, -73, 74, 75, 76, 77, 78, 79, 80, -81, 82, 83, 84, 85, 86, 87, 88, -89, 90, 95, 95, 95, 95, 95, 95, -97, 98, 99, 100, 101, 102, 103, 104, -105, 106, 107, 108, 109, 110, 111, 112, -113, 114, 115, 116, 117, 118, 119, 120, -121, 122, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 95, 95, -95, 95, 95, 95, 95, 95, 183, 95, -95, 95, 95, 95, 95, 95, 95, 192, -193, 194, 195, 196, 197, 198, 199, 200, -201, 202, 203, 204, 205, 206, 207, 208, -209, 210, 211, 212, 213, 214, 95, 216, -217, 218, 219, 220, 221, 222, 223, 224, -225, 226, 227, 228, 229, 230, 231, 232, -233, 234, 235, 236, 237, 238, 239, 240, -241, 242, 243, 244, 245, 246, 95, 248, -249, 250, 251, 252, 253, 254, 255}; - -typedef std::map< std::string, std::vector > map_string_list; -map_string_list global_id_map; - -/** Look at documentation of translate_map */ -static std::string translate_id(const std::string &id) -{ - if (id.size() == 0) - { return id; } - std::string id_translated = id; - id_translated[0] = translate_start_name_map[(unsigned int)id_translated[0]]; - for (unsigned int i=1; i < id_translated.size(); i++) - { - id_translated[i] = translate_name_map[(unsigned int)id_translated[i]]; - } - // It's so much workload now, the if() should speed up things. - if (id_translated != id) - { - // Search duplicates - map_string_list::iterator iter = global_id_map.find(id_translated); - if (iter != global_id_map.end()) - { - unsigned int i = 0; - bool found = false; - for (i=0; i < iter->second.size(); i++) - { - if (id == iter->second[i]) - { - found = true; - break; - } - } - bool convert = false; - if (found) - { - if (i > 0) - { convert = true; } - } - else - { - convert = true; - global_id_map[id_translated].push_back(id); - } - if (convert) - { - std::stringstream out; - out << ++i; - id_translated += out.str(); - } - } - else { global_id_map[id_translated].push_back(id); } - } - return id_translated; -} - -static std::string id_name(void *id) -{ - return ((ID*)id)->name + 2; -} - -static std::string get_geometry_id(Object *ob) -{ - return translate_id(id_name(ob)) + "-mesh"; -} - -static std::string get_light_id(Object *ob) -{ - return translate_id(id_name(ob)) + "-light"; -} - -static std::string get_camera_id(Object *ob) -{ - return translate_id(id_name(ob)) + "-camera"; -} - -std::string get_joint_id(Bone *bone, Object *ob_arm) -{ - return translate_id(id_name(ob_arm) + "_" + bone->name); -} /* @@ -321,34 +169,6 @@ void forEachObjectInScene(Scene *sce, Functor &f) } } -template -void forEachCameraObjectInScene(Scene *sce, Functor &f) -{ - Base *base= (Base*) sce->base.first; - while(base) { - Object *ob = base->object; - - if (ob->type == OB_CAMERA && ob->data) { - f(ob, sce); - } - base= base->next; - } -} - -template -void forEachLampObjectInScene(Scene *sce, Functor &f) -{ - Base *base= (Base*) sce->base.first; - while(base) { - Object *ob = base->object; - - if (ob->type == OB_LAMP && ob->data) { - f(ob); - } - base= base->next; - } -} - // used in forEachMaterialInScene template class ForEachMaterialFunctor @@ -1869,108 +1689,6 @@ public: } }; -class CamerasExporter: COLLADASW::LibraryCameras -{ -public: - CamerasExporter(COLLADASW::StreamWriter *sw): COLLADASW::LibraryCameras(sw){} - void exportCameras(Scene *sce) - { - openLibrary(); - - forEachCameraObjectInScene(sce, *this); - - closeLibrary(); - } - void operator()(Object *ob, Scene *sce) - { - // TODO: shiftx, shifty, YF_dofdist - Camera *cam = (Camera*)ob->data; - std::string cam_id(get_camera_id(ob)); - std::string cam_name(id_name(cam)); - - if (cam->type == CAM_PERSP) { - COLLADASW::PerspectiveOptic persp(mSW); - persp.setXFov(lens_to_angle(cam->lens)*(180.0f/M_PI)); - persp.setAspectRatio(1.0); - persp.setZFar(cam->clipend); - persp.setZNear(cam->clipsta); - COLLADASW::Camera ccam(mSW, &persp, cam_id, cam_name); - addCamera(ccam); - } - else { - COLLADASW::OrthographicOptic ortho(mSW); - ortho.setXMag(cam->ortho_scale); - ortho.setAspectRatio(1.0); - ortho.setZFar(cam->clipend); - ortho.setZNear(cam->clipsta); - COLLADASW::Camera ccam(mSW, &ortho, cam_id, cam_name); - addCamera(ccam); - } - } -}; - -class LightsExporter: COLLADASW::LibraryLights -{ -public: - LightsExporter(COLLADASW::StreamWriter *sw): COLLADASW::LibraryLights(sw){} - void exportLights(Scene *sce) - { - openLibrary(); - - forEachLampObjectInScene(sce, *this); - - closeLibrary(); - } - void operator()(Object *ob) - { - Lamp *la = (Lamp*)ob->data; - std::string la_id(get_light_id(ob)); - std::string la_name(id_name(la)); - COLLADASW::Color col(la->r, la->g, la->b); - float e = la->energy; - - // sun - if (la->type == LA_SUN) { - COLLADASW::DirectionalLight cla(mSW, la_id, la_name, e); - cla.setColor(col); - addLight(cla); - } - // hemi - else if (la->type == LA_HEMI) { - COLLADASW::AmbientLight cla(mSW, la_id, la_name, e); - cla.setColor(col); - addLight(cla); - } - // spot - else if (la->type == LA_SPOT) { - COLLADASW::SpotLight cla(mSW, la_id, la_name, e); - cla.setColor(col); - cla.setFallOffAngle(la->spotsize); - cla.setFallOffExponent(la->spotblend); - cla.setLinearAttenuation(la->att1); - cla.setQuadraticAttenuation(la->att2); - addLight(cla); - } - // lamp - else if (la->type == LA_LOCAL) { - COLLADASW::PointLight cla(mSW, la_id, la_name, e); - cla.setColor(col); - cla.setLinearAttenuation(la->att1); - cla.setQuadraticAttenuation(la->att2); - addLight(cla); - } - // area lamp is not supported - // it will be exported as a local lamp - else { - COLLADASW::PointLight cla(mSW, la_id, la_name, e); - cla.setColor(col); - cla.setLinearAttenuation(la->att1); - cla.setQuadraticAttenuation(la->att2); - addLight(cla); - } - } -}; - // TODO: it would be better to instantiate animations rather than create a new one per object // COLLADA allows this through multiple s in . // For this to work, we need to know objects that use a certain action. @@ -2584,8 +2302,8 @@ protected: void DocumentExporter::exportCurrentScene(Scene *sce, const char* filename) { - global_id_map.clear(); - + clear_global_id_map(); + COLLADABU::NativeString native_filename = COLLADABU::NativeString(std::string(filename)); COLLADASW::StreamWriter sw(native_filename); diff --git a/source/blender/collada/LightExporter.cpp b/source/blender/collada/LightExporter.cpp new file mode 100644 index 00000000000..0bedce41bc0 --- /dev/null +++ b/source/blender/collada/LightExporter.cpp @@ -0,0 +1,106 @@ +/** + * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed, + * Nathan Letwory + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include + +#include "COLLADASWColor.h" +#include "COLLADASWLight.h" + +#include "DNA_lamp_types.h" + +#include "LightExporter.h" +#include "collada_internal.h" + +template +void forEachLampObjectInScene(Scene *sce, Functor &f) +{ + Base *base= (Base*) sce->base.first; + while(base) { + Object *ob = base->object; + + if (ob->type == OB_LAMP && ob->data) { + f(ob); + } + base= base->next; + } +} + +LightsExporter::LightsExporter(COLLADASW::StreamWriter *sw): COLLADASW::LibraryLights(sw){} +void LightsExporter::exportLights(Scene *sce) +{ + openLibrary(); + + forEachLampObjectInScene(sce, *this); + + closeLibrary(); +} +void LightsExporter::operator()(Object *ob) +{ + Lamp *la = (Lamp*)ob->data; + std::string la_id(get_light_id(ob)); + std::string la_name(id_name(la)); + COLLADASW::Color col(la->r, la->g, la->b); + float e = la->energy; + + // sun + if (la->type == LA_SUN) { + COLLADASW::DirectionalLight cla(mSW, la_id, la_name, e); + cla.setColor(col); + addLight(cla); + } + // hemi + else if (la->type == LA_HEMI) { + COLLADASW::AmbientLight cla(mSW, la_id, la_name, e); + cla.setColor(col); + addLight(cla); + } + // spot + else if (la->type == LA_SPOT) { + COLLADASW::SpotLight cla(mSW, la_id, la_name, e); + cla.setColor(col); + cla.setFallOffAngle(la->spotsize); + cla.setFallOffExponent(la->spotblend); + cla.setLinearAttenuation(la->att1); + cla.setQuadraticAttenuation(la->att2); + addLight(cla); + } + // lamp + else if (la->type == LA_LOCAL) { + COLLADASW::PointLight cla(mSW, la_id, la_name, e); + cla.setColor(col); + cla.setLinearAttenuation(la->att1); + cla.setQuadraticAttenuation(la->att2); + addLight(cla); + } + // area lamp is not supported + // it will be exported as a local lamp + else { + COLLADASW::PointLight cla(mSW, la_id, la_name, e); + cla.setColor(col); + cla.setLinearAttenuation(la->att1); + cla.setQuadraticAttenuation(la->att2); + addLight(cla); + } +} diff --git a/source/blender/collada/LightExporter.h b/source/blender/collada/LightExporter.h new file mode 100644 index 00000000000..70fa88d6193 --- /dev/null +++ b/source/blender/collada/LightExporter.h @@ -0,0 +1,43 @@ +/** + * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed, + * Nathan Letwory + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __LIGHTEXPORTER_H__ +#define __LIGHTEXPORTER_H__ + +#include "COLLADASWStreamWriter.h" +#include "COLLADASWLibraryLights.h" + +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +class LightsExporter: COLLADASW::LibraryLights +{ +public: + LightsExporter(COLLADASW::StreamWriter *sw); + void exportLights(Scene *sce); + void operator()(Object *ob); +}; + +#endif diff --git a/source/blender/collada/collada_internal.cpp b/source/blender/collada/collada_internal.cpp new file mode 100644 index 00000000000..cfa94e60199 --- /dev/null +++ b/source/blender/collada/collada_internal.cpp @@ -0,0 +1,240 @@ +/** + * $Id: collada_internal.h 32309 2010-10-05 00:05:14Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "collada_internal.h" + +UnitConverter::UnitConverter() : unit(), up_axis(COLLADAFW::FileInfo::Z_UP) {} + +void UnitConverter::read_asset(const COLLADAFW::FileInfo* asset) +{ +} + +// TODO +// convert vector vec from COLLADA format to Blender +void UnitConverter::convertVec3(float *vec) +{ +} + +// TODO need also for angle conversion, time conversion... + +void UnitConverter::dae_matrix_to_mat4_(float out[][4], const COLLADABU::Math::Matrix4& in) +{ + // in DAE, matrices use columns vectors, (see comments in COLLADABUMathMatrix4.h) + // so here, to make a blender matrix, we swap columns and rows + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + out[i][j] = in[j][i]; + } + } +} + +void UnitConverter::mat4_to_dae(float out[][4], float in[][4]) +{ + copy_m4_m4(out, in); + transpose_m4(out); +} + +void UnitConverter::mat4_to_dae_double(double out[][4], float in[][4]) +{ + float mat[4][4]; + + mat4_to_dae(mat, in); + + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + out[i][j] = mat[i][j]; +} + +void TransformBase::decompose(float mat[][4], float *loc, float eul[3], float quat[4], float *size) +{ + mat4_to_size(size, mat); + if (eul) { + mat4_to_eul(eul, mat); + } + if (quat) { + mat4_to_quat(quat, mat); + } + copy_v3_v3(loc, mat[3]); +} + +/** +Translation map. +Used to translate every COLLADA id to a valid id, no matter what "wrong" letters may be +included. Look at the IDREF XSD declaration for more. +Follows strictly the COLLADA XSD declaration which explicitly allows non-english chars, +like special chars (e.g. micro sign), umlauts and so on. +The COLLADA spec also allows additional chars for member access ('.'), these +must obviously be removed too, otherwise they would be heavily misinterpreted. +*/ +const unsigned char translate_start_name_map[256] = { +95, 95, 95, 95, 95, 95, 95, 95, 95, +95, 95, 95, 95, 95, 95, 95, 95, +95, 95, 95, 95, 95, 95, 95, 95, +95, 95, 95, 95, 95, 95, 95, 95, +95, 95, 95, 95, 95, 95, 95, 95, +95, 95, 95, 95, 95, 95, 95, 95, +95, 95, 95, 95, 95, 95, 95, 95, +95, 95, 95, 95, 95, 95, 95, 95, +65, 66, 67, 68, 69, 70, 71, 72, +73, 74, 75, 76, 77, 78, 79, 80, +81, 82, 83, 84, 85, 86, 87, 88, +89, 90, 95, 95, 95, 95, 95, 95, +97, 98, 99, 100, 101, 102, 103, 104, +105, 106, 107, 108, 109, 110, 111, 112, +113, 114, 115, 116, 117, 118, 119, 120, +121, 122, 95, 95, 95, 95, 95, 95, +95, 95, 95, 95, 95, 95, 95, 95, +95, 95, 95, 95, 95, 95, 95, 95, +95, 95, 95, 95, 95, 95, 95, 95, +95, 95, 95, 95, 95, 95, 95, 95, +95, 95, 95, 95, 95, 95, 95, 95, +95, 95, 95, 95, 95, 95, 95, 95, +95, 95, 95, 95, 95, 95, 95, 95, +95, 95, 95, 95, 95, 95, 95, 192, +193, 194, 195, 196, 197, 198, 199, 200, +201, 202, 203, 204, 205, 206, 207, 208, +209, 210, 211, 212, 213, 214, 95, 216, +217, 218, 219, 220, 221, 222, 223, 224, +225, 226, 227, 228, 229, 230, 231, 232, +233, 234, 235, 236, 237, 238, 239, 240, +241, 242, 243, 244, 245, 246, 95, 248, +249, 250, 251, 252, 253, 254, 255}; + +const unsigned char translate_name_map[256] = { +95, 95, 95, 95, 95, 95, 95, 95, 95, +95, 95, 95, 95, 95, 95, 95, 95, +95, 95, 95, 95, 95, 95, 95, 95, +95, 95, 95, 95, 95, 95, 95, 95, +95, 95, 95, 95, 95, 95, 95, 95, +95, 95, 95, 95, 45, 95, 95, 48, +49, 50, 51, 52, 53, 54, 55, 56, +57, 95, 95, 95, 95, 95, 95, 95, +65, 66, 67, 68, 69, 70, 71, 72, +73, 74, 75, 76, 77, 78, 79, 80, +81, 82, 83, 84, 85, 86, 87, 88, +89, 90, 95, 95, 95, 95, 95, 95, +97, 98, 99, 100, 101, 102, 103, 104, +105, 106, 107, 108, 109, 110, 111, 112, +113, 114, 115, 116, 117, 118, 119, 120, +121, 122, 95, 95, 95, 95, 95, 95, +95, 95, 95, 95, 95, 95, 95, 95, +95, 95, 95, 95, 95, 95, 95, 95, +95, 95, 95, 95, 95, 95, 95, 95, +95, 95, 95, 95, 95, 95, 95, 95, +95, 95, 95, 95, 95, 95, 95, 95, +95, 95, 95, 95, 95, 95, 95, 95, +95, 95, 95, 95, 95, 95, 183, 95, +95, 95, 95, 95, 95, 95, 95, 192, +193, 194, 195, 196, 197, 198, 199, 200, +201, 202, 203, 204, 205, 206, 207, 208, +209, 210, 211, 212, 213, 214, 95, 216, +217, 218, 219, 220, 221, 222, 223, 224, +225, 226, 227, 228, 229, 230, 231, 232, +233, 234, 235, 236, 237, 238, 239, 240, +241, 242, 243, 244, 245, 246, 95, 248, +249, 250, 251, 252, 253, 254, 255}; + +typedef std::map< std::string, std::vector > map_string_list; +map_string_list global_id_map; + +void clear_global_id_map() +{ + global_id_map.clear(); +} + +/** Look at documentation of translate_map */ +std::string translate_id(const std::string &id) +{ + if (id.size() == 0) + { return id; } + std::string id_translated = id; + id_translated[0] = translate_start_name_map[(unsigned int)id_translated[0]]; + for (unsigned int i=1; i < id_translated.size(); i++) + { + id_translated[i] = translate_name_map[(unsigned int)id_translated[i]]; + } + // It's so much workload now, the if() should speed up things. + if (id_translated != id) + { + // Search duplicates + map_string_list::iterator iter = global_id_map.find(id_translated); + if (iter != global_id_map.end()) + { + unsigned int i = 0; + bool found = false; + for (i=0; i < iter->second.size(); i++) + { + if (id == iter->second[i]) + { + found = true; + break; + } + } + bool convert = false; + if (found) + { + if (i > 0) + { convert = true; } + } + else + { + convert = true; + global_id_map[id_translated].push_back(id); + } + if (convert) + { + std::stringstream out; + out << ++i; + id_translated += out.str(); + } + } + else { global_id_map[id_translated].push_back(id); } + } + return id_translated; +} + +std::string id_name(void *id) +{ + return ((ID*)id)->name + 2; +} + +std::string get_geometry_id(Object *ob) +{ + return translate_id(id_name(ob)) + "-mesh"; +} + +std::string get_light_id(Object *ob) +{ + return translate_id(id_name(ob)) + "-light"; +} + +std::string get_joint_id(Bone *bone, Object *ob_arm) +{ + return translate_id(id_name(ob_arm) + "_" + bone->name); +} + +std::string get_camera_id(Object *ob) +{ + return translate_id(id_name(ob)) + "-camera"; +} diff --git a/source/blender/collada/collada_internal.h b/source/blender/collada/collada_internal.h index f8fbe71e6d9..1e3546263da 100644 --- a/source/blender/collada/collada_internal.h +++ b/source/blender/collada/collada_internal.h @@ -24,9 +24,15 @@ #ifndef BLENDER_COLLADA_H #define BLENDER_COLLADA_H +#include +#include +#include + #include "COLLADAFWFileInfo.h" #include "Math/COLLADABUMathMatrix4.h" +#include "DNA_armature_types.h" +#include "DNA_object_types.h" #include "BLI_math.h" class UnitConverter @@ -38,63 +44,41 @@ private: public: // Initialize with Z_UP, since Blender uses right-handed, z-up - UnitConverter() : unit(), up_axis(COLLADAFW::FileInfo::Z_UP) {} + UnitConverter(); - void read_asset(const COLLADAFW::FileInfo* asset) - { - } + void read_asset(const COLLADAFW::FileInfo* asset); // TODO // convert vector vec from COLLADA format to Blender - void convertVec3(float *vec) - { - } + void convertVec3(float *vec); // TODO need also for angle conversion, time conversion... - void dae_matrix_to_mat4_(float out[][4], const COLLADABU::Math::Matrix4& in) - { - // in DAE, matrices use columns vectors, (see comments in COLLADABUMathMatrix4.h) - // so here, to make a blender matrix, we swap columns and rows - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - out[i][j] = in[j][i]; - } - } - } - - void mat4_to_dae(float out[][4], float in[][4]) - { - copy_m4_m4(out, in); - transpose_m4(out); - } - - void mat4_to_dae_double(double out[][4], float in[][4]) - { - float mat[4][4]; - - mat4_to_dae(mat, in); - - for (int i = 0; i < 4; i++) - for (int j = 0; j < 4; j++) - out[i][j] = mat[i][j]; - } + void dae_matrix_to_mat4_(float out[][4], const COLLADABU::Math::Matrix4& in); + + void mat4_to_dae(float out[][4], float in[][4]); + + void mat4_to_dae_double(double out[][4], float in[][4]); }; class TransformBase { public: - void decompose(float mat[][4], float *loc, float eul[3], float quat[4], float *size) - { - mat4_to_size(size, mat); - if (eul) { - mat4_to_eul(eul, mat); - } - if (quat) { - mat4_to_quat(quat, mat); - } - copy_v3_v3(loc, mat[3]); - } + void decompose(float mat[][4], float *loc, float eul[3], float quat[4], float *size); }; +extern void clear_global_id_map(); +/** Look at documentation of translate_map */ +extern std::string translate_id(const std::string &id); + +extern std::string id_name(void *id); + +extern std::string get_geometry_id(Object *ob); + +extern std::string get_light_id(Object *ob); + +extern std::string get_joint_id(Bone *bone, Object *ob_arm); + +extern std::string get_camera_id(Object *ob); + #endif -- cgit v1.2.3 From 20d0236f10f1ae59734be692e7f42c188152f439 Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Wed, 6 Oct 2010 07:57:55 +0000 Subject: Fix for [#24134] pointcache memory error (crash) --- source/blender/blenkernel/intern/pointcache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index e1006cd99cd..4ec12b3482c 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -1890,7 +1890,7 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra) } if(cache->cached_frames) - cache->cached_frames[cfra] = 1; + cache->cached_frames[cfra-cache->startframe] = 1; if(pf) ptcache_file_close(pf); -- cgit v1.2.3 From c88a46e585ff5924be6ec2b5b8cdf9d2ff8faefa Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Wed, 6 Oct 2010 09:53:06 +0000 Subject: COLLADACOLLADA exporter: split geometry export into own files. --- source/blender/blenkernel/BKE_customdata.h | 8 + source/blender/collada/DocumentExporter.cpp | 480 +--------------------------- source/blender/collada/GeometryExporter.cpp | 472 +++++++++++++++++++++++++++ source/blender/collada/GeometryExporter.h | 114 +++++++ 4 files changed, 603 insertions(+), 471 deletions(-) create mode 100644 source/blender/collada/GeometryExporter.cpp create mode 100644 source/blender/collada/GeometryExporter.h (limited to 'source/blender') diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 84eb8ef5300..5d306e75db9 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -32,6 +32,10 @@ #ifndef BKE_CUSTOMDATA_H #define BKE_CUSTOMDATA_H +#ifdef __cplusplus +extern "C" { +#endif + struct ID; struct CustomData; struct CustomDataLayer; @@ -295,5 +299,9 @@ void CustomData_external_read(struct CustomData *data, void CustomData_external_reload(struct CustomData *data, struct ID *id, CustomDataMask mask, int totelem); +#ifdef __cplusplus +} +#endif + #endif diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp index 661f31f5210..0a3166c37c3 100644 --- a/source/blender/collada/DocumentExporter.cpp +++ b/source/blender/collada/DocumentExporter.cpp @@ -34,8 +34,8 @@ extern "C" #include "DNA_image_types.h" #include "DNA_material_types.h" #include "DNA_texture_types.h" -#include "DNA_camera_types.h" -#include "DNA_lamp_types.h" +//#include "DNA_camera_types.h" +//#include "DNA_lamp_types.h" #include "DNA_anim_types.h" #include "DNA_action_types.h" #include "DNA_curve_types.h" @@ -74,7 +74,7 @@ extern char build_rev[]; #include "COLLADASWAsset.h" #include "COLLADASWLibraryVisualScenes.h" #include "COLLADASWNode.h" -#include "COLLADASWLibraryGeometries.h" +//#include "COLLADASWLibraryGeometries.h" #include "COLLADASWSource.h" #include "COLLADASWInstanceGeometry.h" #include "COLLADASWInputList.h" @@ -96,7 +96,7 @@ extern char build_rev[]; #include "COLLADASWLibraryMaterials.h" #include "COLLADASWBindMaterial.h" //#include "COLLADASWLibraryCameras.h" -#include "COLLADASWLibraryLights.h" +//#include "COLLADASWLibraryLights.h" #include "COLLADASWInstanceCamera.h" #include "COLLADASWInstanceLight.h" //#include "COLLADASWCameraOptic.h" @@ -110,6 +110,7 @@ extern char build_rev[]; #include "CameraExporter.h" #include "LightExporter.h" +#include "GeometryExporter.h" #include #include // std::find @@ -138,23 +139,6 @@ char *CustomData_get_active_layer_name(const CustomData *data, int type) Definition can take some time to understand, but they should be useful. */ -// f should have -// void operator()(Object* ob) -template -void forEachMeshObjectInScene(Scene *sce, Functor &f) -{ - - Base *base= (Base*) sce->base.first; - while(base) { - Object *ob = base->object; - - if (ob->type == OB_MESH && ob->data) { - f(ob); - } - base= base->next; - - } -} template void forEachObjectInScene(Scene *sce, Functor &f) @@ -203,7 +187,8 @@ template void forEachMaterialInScene(Scene *sce, Functor &f) { ForEachMaterialFunctor matfunc(&f); - forEachMeshObjectInScene(sce, matfunc); + GeometryFunctor gf; + gf.forEachMeshObjectInScene>(sce, matfunc); } // OB_MESH is assumed @@ -218,454 +203,6 @@ std::string getActiveUVLayerName(Object *ob) return ""; } -// TODO: optimize UV sets by making indexed list with duplicates removed -class GeometryExporter : COLLADASW::LibraryGeometries -{ - struct Face - { - unsigned int v1, v2, v3, v4; - }; - - struct Normal - { - float x, y, z; - }; - - Scene *mScene; - -public: - GeometryExporter(COLLADASW::StreamWriter *sw) : COLLADASW::LibraryGeometries(sw) {} - - void exportGeom(Scene *sce) - { - openLibrary(); - - mScene = sce; - forEachMeshObjectInScene(sce, *this); - - closeLibrary(); - } - - void operator()(Object *ob) - { - // XXX don't use DerivedMesh, Mesh instead? - -#if 0 - DerivedMesh *dm = mesh_get_derived_final(mScene, ob, CD_MASK_BAREMESH); -#endif - Mesh *me = (Mesh*)ob->data; - std::string geom_id = get_geometry_id(ob); - std::vector nor; - std::vector norind; - - bool has_color = (bool)CustomData_has_layer(&me->fdata, CD_MCOL); - - create_normals(nor, norind, me); - - // openMesh(geoId, geoName, meshId) - openMesh(geom_id); - - // writes for vertex coords - createVertsSource(geom_id, me); - - // writes for normal coords - createNormalsSource(geom_id, me, nor); - - bool has_uvs = (bool)CustomData_has_layer(&me->fdata, CD_MTFACE); - - // writes for uv coords if mesh has uv coords - if (has_uvs) - createTexcoordsSource(geom_id, me); - - if (has_color) - createVertexColorSource(geom_id, me); - - // - COLLADASW::Vertices verts(mSW); - verts.setId(getIdBySemantics(geom_id, COLLADASW::VERTEX)); - COLLADASW::InputList &input_list = verts.getInputList(); - COLLADASW::Input input(COLLADASW::POSITION, getUrlBySemantics(geom_id, COLLADASW::POSITION)); - input_list.push_back(input); - verts.add(); - - // XXX slow - if (ob->totcol) { - for(int a = 0; a < ob->totcol; a++) { - createPolylist(a, has_uvs, has_color, ob, geom_id, norind); - } - } - else { - createPolylist(0, has_uvs, has_color, ob, geom_id, norind); - } - - closeMesh(); - closeGeometry(); - -#if 0 - dm->release(dm); -#endif - } - - // powerful because it handles both cases when there is material and when there's not - void createPolylist(int material_index, - bool has_uvs, - bool has_color, - Object *ob, - std::string& geom_id, - std::vector& norind) - { - Mesh *me = (Mesh*)ob->data; - MFace *mfaces = me->mface; - int totfaces = me->totface; - - // - int i; - int faces_in_polylist = 0; - std::vector vcount_list; - - // count faces with this material - for (i = 0; i < totfaces; i++) { - MFace *f = &mfaces[i]; - - if (f->mat_nr == material_index) { - faces_in_polylist++; - if (f->v4 == 0) { - vcount_list.push_back(3); - } - else { - vcount_list.push_back(4); - } - } - } - - // no faces using this material - if (faces_in_polylist == 0) { - fprintf(stderr, "%s: no faces use material %d\n", id_name(ob).c_str(), material_index); - return; - } - - Material *ma = ob->totcol ? give_current_material(ob, material_index + 1) : NULL; - COLLADASW::Polylist polylist(mSW); - - // sets count attribute in - polylist.setCount(faces_in_polylist); - - // sets material name - if (ma) { - polylist.setMaterial(translate_id(id_name(ma))); - } - - COLLADASW::InputList &til = polylist.getInputList(); - - // creates in for vertices - COLLADASW::Input input1(COLLADASW::VERTEX, getUrlBySemantics(geom_id, COLLADASW::VERTEX), 0); - - // creates in for normals - COLLADASW::Input input2(COLLADASW::NORMAL, getUrlBySemantics(geom_id, COLLADASW::NORMAL), 1); - - til.push_back(input1); - til.push_back(input2); - - // if mesh has uv coords writes for TEXCOORD - int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE); - - for (i = 0; i < num_layers; i++) { - // char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, i); - COLLADASW::Input input3(COLLADASW::TEXCOORD, - makeUrl(makeTexcoordSourceId(geom_id, i)), - 2, // offset always 2, this is only until we have optimized UV sets - i // set number equals UV layer index - ); - til.push_back(input3); - } - - if (has_color) { - COLLADASW::Input input4(COLLADASW::COLOR, getUrlBySemantics(geom_id, COLLADASW::COLOR), has_uvs ? 3 : 2); - til.push_back(input4); - } - - // sets - polylist.setVCountList(vcount_list); - - // performs the actual writing - polylist.prepareToAppendValues(); - - //

- int texindex = 0; - for (i = 0; i < totfaces; i++) { - MFace *f = &mfaces[i]; - - if (f->mat_nr == material_index) { - - unsigned int *v = &f->v1; - unsigned int *n = &norind[i].v1; - for (int j = 0; j < (f->v4 == 0 ? 3 : 4); j++) { - polylist.appendValues(v[j]); - polylist.appendValues(n[j]); - - if (has_uvs) - polylist.appendValues(texindex + j); - - if (has_color) - polylist.appendValues(texindex + j); - } - } - - texindex += 3; - if (f->v4 != 0) - texindex++; - } - - polylist.finish(); - } - - // creates for positions - void createVertsSource(std::string geom_id, Mesh *me) - { -#if 0 - int totverts = dm->getNumVerts(dm); - MVert *verts = dm->getVertArray(dm); -#endif - int totverts = me->totvert; - MVert *verts = me->mvert; - - COLLADASW::FloatSourceF source(mSW); - source.setId(getIdBySemantics(geom_id, COLLADASW::POSITION)); - source.setArrayId(getIdBySemantics(geom_id, COLLADASW::POSITION) + - ARRAY_ID_SUFFIX); - source.setAccessorCount(totverts); - source.setAccessorStride(3); - COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); - param.push_back("X"); - param.push_back("Y"); - param.push_back("Z"); - /*main function, it creates , */ - source.prepareToAppendValues(); - //appends data to - int i = 0; - for (i = 0; i < totverts; i++) { - source.appendValues(verts[i].co[0], verts[i].co[1], verts[i].co[2]); - } - - source.finish(); - - } - - void createVertexColorSource(std::string geom_id, Mesh *me) - { - if (!CustomData_has_layer(&me->fdata, CD_MCOL)) - return; - - MFace *f; - int totcolor = 0, i, j; - - for (i = 0, f = me->mface; i < me->totface; i++, f++) - totcolor += f->v4 ? 4 : 3; - - COLLADASW::FloatSourceF source(mSW); - source.setId(getIdBySemantics(geom_id, COLLADASW::COLOR)); - source.setArrayId(getIdBySemantics(geom_id, COLLADASW::COLOR) + ARRAY_ID_SUFFIX); - source.setAccessorCount(totcolor); - source.setAccessorStride(3); - - COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); - param.push_back("R"); - param.push_back("G"); - param.push_back("B"); - - source.prepareToAppendValues(); - - int index = CustomData_get_active_layer_index(&me->fdata, CD_MCOL); - - MCol *mcol = (MCol*)me->fdata.layers[index].data; - MCol *c = mcol; - - for (i = 0, f = me->mface; i < me->totface; i++, c += 4, f++) - for (j = 0; j < (f->v4 ? 4 : 3); j++) - source.appendValues(c[j].b / 255.0f, c[j].g / 255.0f, c[j].r / 255.0f); - - source.finish(); - } - - std::string makeTexcoordSourceId(std::string& geom_id, int layer_index) - { - char suffix[20]; - sprintf(suffix, "-%d", layer_index); - return getIdBySemantics(geom_id, COLLADASW::TEXCOORD) + suffix; - } - - //creates for texcoords - void createTexcoordsSource(std::string geom_id, Mesh *me) - { -#if 0 - int totfaces = dm->getNumFaces(dm); - MFace *mfaces = dm->getFaceArray(dm); -#endif - int totfaces = me->totface; - MFace *mfaces = me->mface; - - int totuv = 0; - int i; - - // count totuv - for (i = 0; i < totfaces; i++) { - MFace *f = &mfaces[i]; - if (f->v4 == 0) { - totuv+=3; - } - else { - totuv+=4; - } - } - - int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE); - - // write for each layer - // each will get id like meshName + "map-channel-1" - for (int a = 0; a < num_layers; a++) { - MTFace *tface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, a); - // char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, a); - - COLLADASW::FloatSourceF source(mSW); - std::string layer_id = makeTexcoordSourceId(geom_id, a); - source.setId(layer_id); - source.setArrayId(layer_id + ARRAY_ID_SUFFIX); - - source.setAccessorCount(totuv); - source.setAccessorStride(2); - COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); - param.push_back("S"); - param.push_back("T"); - - source.prepareToAppendValues(); - - for (i = 0; i < totfaces; i++) { - MFace *f = &mfaces[i]; - - for (int j = 0; j < (f->v4 == 0 ? 3 : 4); j++) { - source.appendValues(tface[i].uv[j][0], - tface[i].uv[j][1]); - } - } - - source.finish(); - } - } - - - //creates for normals - void createNormalsSource(std::string geom_id, Mesh *me, std::vector& nor) - { -#if 0 - int totverts = dm->getNumVerts(dm); - MVert *verts = dm->getVertArray(dm); -#endif - - COLLADASW::FloatSourceF source(mSW); - source.setId(getIdBySemantics(geom_id, COLLADASW::NORMAL)); - source.setArrayId(getIdBySemantics(geom_id, COLLADASW::NORMAL) + - ARRAY_ID_SUFFIX); - source.setAccessorCount(nor.size()); - source.setAccessorStride(3); - COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); - param.push_back("X"); - param.push_back("Y"); - param.push_back("Z"); - - source.prepareToAppendValues(); - - std::vector::iterator it; - for (it = nor.begin(); it != nor.end(); it++) { - Normal& n = *it; - source.appendValues(n.x, n.y, n.z); - } - - source.finish(); - } - - void create_normals(std::vector &nor, std::vector &ind, Mesh *me) - { - int i, j, v; - MVert *vert = me->mvert; - std::map nshar; - - for (i = 0; i < me->totface; i++) { - MFace *fa = &me->mface[i]; - Face f; - unsigned int *nn = &f.v1; - unsigned int *vv = &fa->v1; - - memset(&f, 0, sizeof(f)); - v = fa->v4 == 0 ? 3 : 4; - - if (!(fa->flag & ME_SMOOTH)) { - Normal n; - if (v == 4) - normal_quad_v3(&n.x, vert[fa->v1].co, vert[fa->v2].co, vert[fa->v3].co, vert[fa->v4].co); - else - normal_tri_v3(&n.x, vert[fa->v1].co, vert[fa->v2].co, vert[fa->v3].co); - nor.push_back(n); - } - - for (j = 0; j < v; j++) { - if (fa->flag & ME_SMOOTH) { - if (nshar.find(*vv) != nshar.end()) - *nn = nshar[*vv]; - else { - Normal n = { - vert[*vv].no[0]/32767.0, - vert[*vv].no[1]/32767.0, - vert[*vv].no[2]/32767.0 - }; - nor.push_back(n); - *nn = nor.size() - 1; - nshar[*vv] = *nn; - } - vv++; - } - else { - *nn = nor.size() - 1; - } - nn++; - } - - ind.push_back(f); - } - } - - std::string getIdBySemantics(std::string geom_id, COLLADASW::Semantics type, std::string other_suffix = "") { - return geom_id + getSuffixBySemantic(type) + other_suffix; - } - - - COLLADASW::URI getUrlBySemantics(std::string geom_id, COLLADASW::Semantics type, std::string other_suffix = "") { - - std::string id(getIdBySemantics(geom_id, type, other_suffix)); - return COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, id); - - } - - COLLADASW::URI makeUrl(std::string id) - { - return COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, id); - } - - - /* int getTriCount(MFace *faces, int totface) { - int i; - int tris = 0; - for (i = 0; i < totface; i++) { - // if quad - if (faces[i].v4 != 0) - tris += 2; - else - tris++; - } - - return tris; - }*/ -}; class TransformWriter : protected TransformBase { @@ -828,7 +365,8 @@ public: openLibrary(); - forEachMeshObjectInScene(sce, *this); + GeometryFunctor gf; + gf.forEachMeshObjectInScene(sce, *this); closeLibrary(); } diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp new file mode 100644 index 00000000000..b06551a97b6 --- /dev/null +++ b/source/blender/collada/GeometryExporter.cpp @@ -0,0 +1,472 @@ +/** + * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed, + * Nathan Letwory + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "COLLADASWPrimitves.h" +#include "COLLADASWSource.h" +#include "COLLADASWVertices.h" +#include "COLLADABUUtils.h" + +#include "GeometryExporter.h" + +#include "DNA_meshdata_types.h" +#include "BKE_customdata.h" +#include "BKE_material.h" + +#include "collada_internal.h" + +// TODO: optimize UV sets by making indexed list with duplicates removed +GeometryExporter::GeometryExporter(COLLADASW::StreamWriter *sw) : COLLADASW::LibraryGeometries(sw) {} + + +void GeometryExporter::exportGeom(Scene *sce) +{ + openLibrary(); + + mScene = sce; + GeometryFunctor gf; + gf.forEachMeshObjectInScene(sce, *this); + + closeLibrary(); +} + +void GeometryExporter::operator()(Object *ob) +{ + // XXX don't use DerivedMesh, Mesh instead? + +#if 0 + DerivedMesh *dm = mesh_get_derived_final(mScene, ob, CD_MASK_BAREMESH); +#endif + Mesh *me = (Mesh*)ob->data; + std::string geom_id = get_geometry_id(ob); + std::vector nor; + std::vector norind; + + bool has_color = (bool)CustomData_has_layer(&me->fdata, CD_MCOL); + + create_normals(nor, norind, me); + + // openMesh(geoId, geoName, meshId) + openMesh(geom_id); + + // writes for vertex coords + createVertsSource(geom_id, me); + + // writes for normal coords + createNormalsSource(geom_id, me, nor); + + bool has_uvs = (bool)CustomData_has_layer(&me->fdata, CD_MTFACE); + + // writes for uv coords if mesh has uv coords + if (has_uvs) + createTexcoordsSource(geom_id, me); + + if (has_color) + createVertexColorSource(geom_id, me); + + // + COLLADASW::Vertices verts(mSW); + verts.setId(getIdBySemantics(geom_id, COLLADASW::VERTEX)); + COLLADASW::InputList &input_list = verts.getInputList(); + COLLADASW::Input input(COLLADASW::POSITION, getUrlBySemantics(geom_id, COLLADASW::POSITION)); + input_list.push_back(input); + verts.add(); + + // XXX slow + if (ob->totcol) { + for(int a = 0; a < ob->totcol; a++) { + createPolylist(a, has_uvs, has_color, ob, geom_id, norind); + } + } + else { + createPolylist(0, has_uvs, has_color, ob, geom_id, norind); + } + + closeMesh(); + closeGeometry(); + +#if 0 + dm->release(dm); +#endif +} + +// powerful because it handles both cases when there is material and when there's not +void GeometryExporter::createPolylist(int material_index, + bool has_uvs, + bool has_color, + Object *ob, + std::string& geom_id, + std::vector& norind) +{ + Mesh *me = (Mesh*)ob->data; + MFace *mfaces = me->mface; + int totfaces = me->totface; + + // + int i; + int faces_in_polylist = 0; + std::vector vcount_list; + + // count faces with this material + for (i = 0; i < totfaces; i++) { + MFace *f = &mfaces[i]; + + if (f->mat_nr == material_index) { + faces_in_polylist++; + if (f->v4 == 0) { + vcount_list.push_back(3); + } + else { + vcount_list.push_back(4); + } + } + } + + // no faces using this material + if (faces_in_polylist == 0) { + fprintf(stderr, "%s: no faces use material %d\n", id_name(ob).c_str(), material_index); + return; + } + + Material *ma = ob->totcol ? give_current_material(ob, material_index + 1) : NULL; + COLLADASW::Polylist polylist(mSW); + + // sets count attribute in + polylist.setCount(faces_in_polylist); + + // sets material name + if (ma) { + polylist.setMaterial(translate_id(id_name(ma))); + } + + COLLADASW::InputList &til = polylist.getInputList(); + + // creates in for vertices + COLLADASW::Input input1(COLLADASW::VERTEX, getUrlBySemantics(geom_id, COLLADASW::VERTEX), 0); + + // creates in for normals + COLLADASW::Input input2(COLLADASW::NORMAL, getUrlBySemantics(geom_id, COLLADASW::NORMAL), 1); + + til.push_back(input1); + til.push_back(input2); + + // if mesh has uv coords writes for TEXCOORD + int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE); + + for (i = 0; i < num_layers; i++) { + // char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, i); + COLLADASW::Input input3(COLLADASW::TEXCOORD, + makeUrl(makeTexcoordSourceId(geom_id, i)), + 2, // offset always 2, this is only until we have optimized UV sets + i // set number equals UV layer index + ); + til.push_back(input3); + } + + if (has_color) { + COLLADASW::Input input4(COLLADASW::COLOR, getUrlBySemantics(geom_id, COLLADASW::COLOR), has_uvs ? 3 : 2); + til.push_back(input4); + } + + // sets + polylist.setVCountList(vcount_list); + + // performs the actual writing + polylist.prepareToAppendValues(); + + //

+ int texindex = 0; + for (i = 0; i < totfaces; i++) { + MFace *f = &mfaces[i]; + + if (f->mat_nr == material_index) { + + unsigned int *v = &f->v1; + unsigned int *n = &norind[i].v1; + for (int j = 0; j < (f->v4 == 0 ? 3 : 4); j++) { + polylist.appendValues(v[j]); + polylist.appendValues(n[j]); + + if (has_uvs) + polylist.appendValues(texindex + j); + + if (has_color) + polylist.appendValues(texindex + j); + } + } + + texindex += 3; + if (f->v4 != 0) + texindex++; + } + + polylist.finish(); +} + +// creates for positions +void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me) +{ +#if 0 + int totverts = dm->getNumVerts(dm); + MVert *verts = dm->getVertArray(dm); +#endif + int totverts = me->totvert; + MVert *verts = me->mvert; + + COLLADASW::FloatSourceF source(mSW); + source.setId(getIdBySemantics(geom_id, COLLADASW::POSITION)); + source.setArrayId(getIdBySemantics(geom_id, COLLADASW::POSITION) + + ARRAY_ID_SUFFIX); + source.setAccessorCount(totverts); + source.setAccessorStride(3); + COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); + param.push_back("X"); + param.push_back("Y"); + param.push_back("Z"); + /*main function, it creates , */ + source.prepareToAppendValues(); + //appends data to + int i = 0; + for (i = 0; i < totverts; i++) { + source.appendValues(verts[i].co[0], verts[i].co[1], verts[i].co[2]); + } + + source.finish(); + +} + +void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me) +{ + if (!CustomData_has_layer(&me->fdata, CD_MCOL)) + return; + + MFace *f; + int totcolor = 0, i, j; + + for (i = 0, f = me->mface; i < me->totface; i++, f++) + totcolor += f->v4 ? 4 : 3; + + COLLADASW::FloatSourceF source(mSW); + source.setId(getIdBySemantics(geom_id, COLLADASW::COLOR)); + source.setArrayId(getIdBySemantics(geom_id, COLLADASW::COLOR) + ARRAY_ID_SUFFIX); + source.setAccessorCount(totcolor); + source.setAccessorStride(3); + + COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); + param.push_back("R"); + param.push_back("G"); + param.push_back("B"); + + source.prepareToAppendValues(); + + int index = CustomData_get_active_layer_index(&me->fdata, CD_MCOL); + + MCol *mcol = (MCol*)me->fdata.layers[index].data; + MCol *c = mcol; + + for (i = 0, f = me->mface; i < me->totface; i++, c += 4, f++) + for (j = 0; j < (f->v4 ? 4 : 3); j++) + source.appendValues(c[j].b / 255.0f, c[j].g / 255.0f, c[j].r / 255.0f); + + source.finish(); +} + +std::string GeometryExporter::makeTexcoordSourceId(std::string& geom_id, int layer_index) +{ + char suffix[20]; + sprintf(suffix, "-%d", layer_index); + return getIdBySemantics(geom_id, COLLADASW::TEXCOORD) + suffix; +} + +//creates for texcoords +void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me) +{ +#if 0 + int totfaces = dm->getNumFaces(dm); + MFace *mfaces = dm->getFaceArray(dm); +#endif + int totfaces = me->totface; + MFace *mfaces = me->mface; + + int totuv = 0; + int i; + + // count totuv + for (i = 0; i < totfaces; i++) { + MFace *f = &mfaces[i]; + if (f->v4 == 0) { + totuv+=3; + } + else { + totuv+=4; + } + } + + int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE); + + // write for each layer + // each will get id like meshName + "map-channel-1" + for (int a = 0; a < num_layers; a++) { + MTFace *tface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, a); + // char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, a); + + COLLADASW::FloatSourceF source(mSW); + std::string layer_id = makeTexcoordSourceId(geom_id, a); + source.setId(layer_id); + source.setArrayId(layer_id + ARRAY_ID_SUFFIX); + + source.setAccessorCount(totuv); + source.setAccessorStride(2); + COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); + param.push_back("S"); + param.push_back("T"); + + source.prepareToAppendValues(); + + for (i = 0; i < totfaces; i++) { + MFace *f = &mfaces[i]; + + for (int j = 0; j < (f->v4 == 0 ? 3 : 4); j++) { + source.appendValues(tface[i].uv[j][0], + tface[i].uv[j][1]); + } + } + + source.finish(); + } +} + + +//creates for normals +void GeometryExporter::createNormalsSource(std::string geom_id, Mesh *me, std::vector& nor) +{ +#if 0 + int totverts = dm->getNumVerts(dm); + MVert *verts = dm->getVertArray(dm); +#endif + + COLLADASW::FloatSourceF source(mSW); + source.setId(getIdBySemantics(geom_id, COLLADASW::NORMAL)); + source.setArrayId(getIdBySemantics(geom_id, COLLADASW::NORMAL) + + ARRAY_ID_SUFFIX); + source.setAccessorCount((unsigned long)nor.size()); + source.setAccessorStride(3); + COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); + param.push_back("X"); + param.push_back("Y"); + param.push_back("Z"); + + source.prepareToAppendValues(); + + std::vector::iterator it; + for (it = nor.begin(); it != nor.end(); it++) { + Normal& n = *it; + source.appendValues(n.x, n.y, n.z); + } + + source.finish(); +} + +void GeometryExporter::create_normals(std::vector &nor, std::vector &ind, Mesh *me) +{ + int i, j, v; + MVert *vert = me->mvert; + std::map nshar; + + for (i = 0; i < me->totface; i++) { + MFace *fa = &me->mface[i]; + Face f; + unsigned int *nn = &f.v1; + unsigned int *vv = &fa->v1; + + memset(&f, 0, sizeof(f)); + v = fa->v4 == 0 ? 3 : 4; + + if (!(fa->flag & ME_SMOOTH)) { + Normal n; + if (v == 4) + normal_quad_v3(&n.x, vert[fa->v1].co, vert[fa->v2].co, vert[fa->v3].co, vert[fa->v4].co); + else + normal_tri_v3(&n.x, vert[fa->v1].co, vert[fa->v2].co, vert[fa->v3].co); + nor.push_back(n); + } + + for (j = 0; j < v; j++) { + if (fa->flag & ME_SMOOTH) { + if (nshar.find(*vv) != nshar.end()) + *nn = nshar[*vv]; + else { + Normal n = { + vert[*vv].no[0]/32767.0, + vert[*vv].no[1]/32767.0, + vert[*vv].no[2]/32767.0 + }; + nor.push_back(n); + *nn = (unsigned int)nor.size() - 1; + nshar[*vv] = *nn; + } + vv++; + } + else { + *nn = (unsigned int)nor.size() - 1; + } + nn++; + } + + ind.push_back(f); + } +} + +std::string GeometryExporter::getIdBySemantics(std::string geom_id, COLLADASW::Semantics type, std::string other_suffix) { + return geom_id + getSuffixBySemantic(type) + other_suffix; +} + + +COLLADASW::URI GeometryExporter::getUrlBySemantics(std::string geom_id, COLLADASW::Semantics type, std::string other_suffix) { + + std::string id(getIdBySemantics(geom_id, type, other_suffix)); + return COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, id); + +} + +COLLADASW::URI GeometryExporter::makeUrl(std::string id) +{ + return COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, id); +} + + +/* int GeometryExporter::getTriCount(MFace *faces, int totface) { + int i; + int tris = 0; + for (i = 0; i < totface; i++) { + // if quad + if (faces[i].v4 != 0) + tris += 2; + else + tris++; + } + + return tris; + }*/ diff --git a/source/blender/collada/GeometryExporter.h b/source/blender/collada/GeometryExporter.h new file mode 100644 index 00000000000..4ea3cb4efdf --- /dev/null +++ b/source/blender/collada/GeometryExporter.h @@ -0,0 +1,114 @@ +/** + * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed, + * Nathan Letwory + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __GEOMETRYEXPORTER_H__ +#define __GEOMETRYEXPORTER_H__ + +#include +#include + +#include "COLLADASWStreamWriter.h" +#include "COLLADASWLibraryGeometries.h" +#include "COLLADASWInputList.h" + +#include "DNA_mesh_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +// TODO: optimize UV sets by making indexed list with duplicates removed +class GeometryExporter : COLLADASW::LibraryGeometries +{ + struct Face + { + unsigned int v1, v2, v3, v4; + }; + + struct Normal + { + float x, y, z; + }; + + Scene *mScene; + +public: + GeometryExporter(COLLADASW::StreamWriter *sw); + + void exportGeom(Scene *sce); + + void operator()(Object *ob); + + // powerful because it handles both cases when there is material and when there's not + void createPolylist(int material_index, + bool has_uvs, + bool has_color, + Object *ob, + std::string& geom_id, + std::vector& norind); + + // creates for positions + void createVertsSource(std::string geom_id, Mesh *me); + + void createVertexColorSource(std::string geom_id, Mesh *me); + + std::string makeTexcoordSourceId(std::string& geom_id, int layer_index); + + //creates for texcoords + void createTexcoordsSource(std::string geom_id, Mesh *me); + + //creates for normals + void createNormalsSource(std::string geom_id, Mesh *me, std::vector& nor); + + void create_normals(std::vector &nor, std::vector &ind, Mesh *me); + + std::string getIdBySemantics(std::string geom_id, COLLADASW::Semantics type, std::string other_suffix = ""); + + COLLADASW::URI getUrlBySemantics(std::string geom_id, COLLADASW::Semantics type, std::string other_suffix = ""); + + COLLADASW::URI makeUrl(std::string id); + + /* int getTriCount(MFace *faces, int totface);*/ +}; + +struct GeometryFunctor { + // f should have + // void operator()(Object* ob) + template + void forEachMeshObjectInScene(Scene *sce, Functor &f) + { + + Base *base= (Base*) sce->base.first; + while(base) { + Object *ob = base->object; + + if (ob->type == OB_MESH && ob->data) { + f(ob); + } + base= base->next; + + } + } +}; + +#endif -- cgit v1.2.3 From 0321f089d6e7d8321b8b5b3b48b367038b58b0db Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 6 Oct 2010 10:00:15 +0000 Subject: [#24063] Error in RNA naming in SequenceCrop.min_x/y ; [#24153] Typo --- source/blender/editors/object/object_select.c | 4 ++-- source/blender/makesrna/intern/rna_sequencer.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index 818bb50a1fb..20346ab080e 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -660,7 +660,7 @@ static int object_select_by_layer_exec(bContext *C, wmOperator *op) void OBJECT_OT_select_by_layer(wmOperatorType *ot) { /* identifiers */ - ot->name= "select by layer"; + ot->name= "Select by Layer"; ot->description = "Select all visible objects on a layer"; ot->idname= "OBJECT_OT_select_by_layer"; @@ -809,7 +809,7 @@ void OBJECT_OT_select_same_group(wmOperatorType *ot) { /* identifiers */ - ot->name= "select same group"; + ot->name= "Select Same Group"; ot->description = "Select object in the same group"; ot->idname= "OBJECT_OT_select_same_group"; diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index b6a09b9c217..c004f32f586 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -677,13 +677,13 @@ static void rna_def_strip_crop(BlenderRNA *brna) RNA_def_property_ui_range(prop, 0, 4096, 1, 0); RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, "rna_Sequence_update"); - prop= RNA_def_property(srna, "min_x", PROP_INT, PROP_UNSIGNED); + prop= RNA_def_property(srna, "min_y", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "bottom"); RNA_def_property_ui_text(prop, "Bottom", ""); RNA_def_property_ui_range(prop, 0, 4096, 1, 0); RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, "rna_Sequence_update"); - prop= RNA_def_property(srna, "min_y", PROP_INT, PROP_UNSIGNED); + prop= RNA_def_property(srna, "min_x", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "left"); RNA_def_property_ui_text(prop, "Left", ""); RNA_def_property_ui_range(prop, 0, 4096, 1, 0); -- cgit v1.2.3 From d50cadbe0dd5a676c23e40b8a2939345442a4f28 Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Wed, 6 Oct 2010 10:09:44 +0000 Subject: Fix for [#22236] Seg Fault when rendering sequence with speed effect, [#24160] VSE crash * Override the default render name in the case of the sequence renderer scene being included as a strip in the sequencer. * Somebody with deeper insight to the rendering pipeline should probably check if this is the best way to handle this. --- source/blender/blenkernel/intern/sequencer.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source/blender') diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 430d6f87619..8c496fea3b0 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -1861,6 +1861,15 @@ static ImBuf * seq_render_scene_strip_impl( if(rendering) re= RE_NewRender(" do_build_seq_ibuf"); + /* If the top level scene that does the sequencer rendering is included + * as a strip the default render name for the strip will conflict with + * the original render, so override the name in this case. + * See bugs #22236 and #24160 for examples. + * XXX: Somebody with deeper insight to the rendering pipeline should + * probably check if this is the best way to handle this. -jahka + */ + else if(seq->scene == scene) + re= RE_NewRender("scene_conflict_render"); else re= RE_NewRender(sce->id.name); -- cgit v1.2.3 From 7245280f6c9c797e92d51bd10fc1d1127efdd394 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Wed, 6 Oct 2010 11:02:44 +0000 Subject: COLLADA: Split ArmatureExporter, InstanceWriter and TransformWriter into separate files. --- source/blender/collada/ArmatureExporter.cpp | 469 +++++++++++++++++++++++ source/blender/collada/ArmatureExporter.h | 137 +++++++ source/blender/collada/DocumentExporter.cpp | 567 +--------------------------- source/blender/collada/InstanceWriter.cpp | 64 ++++ source/blender/collada/InstanceWriter.h | 39 ++ source/blender/collada/TransformWriter.cpp | 100 +++++ source/blender/collada/TransformWriter.h | 48 +++ 7 files changed, 866 insertions(+), 558 deletions(-) create mode 100644 source/blender/collada/ArmatureExporter.cpp create mode 100644 source/blender/collada/ArmatureExporter.h create mode 100644 source/blender/collada/InstanceWriter.cpp create mode 100644 source/blender/collada/InstanceWriter.h create mode 100644 source/blender/collada/TransformWriter.cpp create mode 100644 source/blender/collada/TransformWriter.h (limited to 'source/blender') diff --git a/source/blender/collada/ArmatureExporter.cpp b/source/blender/collada/ArmatureExporter.cpp new file mode 100644 index 00000000000..527ccd66577 --- /dev/null +++ b/source/blender/collada/ArmatureExporter.cpp @@ -0,0 +1,469 @@ +/** + * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed, + * Nathan Letwory + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "COLLADASWBaseInputElement.h" +#include "COLLADASWInstanceController.h" +#include "COLLADASWPrimitves.h" +#include "COLLADASWSource.h" + +#include "DNA_action_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_modifier_types.h" + +#include "BKE_action.h" +#include "BKE_armature.h" + +#include "BLI_listBase.h" + +#include "GeometryExporter.h" +#include "ArmatureExporter.h" + +// XXX exporter writes wrong data for shared armatures. A separate +// controller should be written for each armature-mesh binding how do +// we make controller ids then? +ArmatureExporter::ArmatureExporter(COLLADASW::StreamWriter *sw) : COLLADASW::LibraryControllers(sw) {} + +// write bone nodes +void ArmatureExporter::add_armature_bones(Object *ob_arm, Scene *sce) +{ + // write bone nodes + bArmature *arm = (bArmature*)ob_arm->data; + for (Bone *bone = (Bone*)arm->bonebase.first; bone; bone = bone->next) { + // start from root bones + if (!bone->parent) + add_bone_node(bone, ob_arm); + } +} + +bool ArmatureExporter::is_skinned_mesh(Object *ob) +{ + return get_assigned_armature(ob) != NULL; +} + +void ArmatureExporter::add_instance_controller(Object *ob) +{ + Object *ob_arm = get_assigned_armature(ob); + bArmature *arm = (bArmature*)ob_arm->data; + + const std::string& controller_id = get_controller_id(ob_arm, ob); + + COLLADASW::InstanceController ins(mSW); + ins.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, controller_id)); + + // write root bone URLs + Bone *bone; + for (bone = (Bone*)arm->bonebase.first; bone; bone = bone->next) { + if (!bone->parent) + ins.addSkeleton(COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, get_joint_id(bone, ob_arm))); + } + + InstanceWriter::add_material_bindings(ins.getBindMaterial(), ob); + + ins.add(); +} + +void ArmatureExporter::export_controllers(Scene *sce) +{ + scene = sce; + + openLibrary(); + + GeometryFunctor gf; + gf.forEachMeshObjectInScene(sce, *this); + + closeLibrary(); +} + +void ArmatureExporter::operator()(Object *ob) +{ + Object *ob_arm = get_assigned_armature(ob); + + if (ob_arm /*&& !already_written(ob_arm)*/) + export_controller(ob, ob_arm); +} +#if 0 + +bool ArmatureExporter::already_written(Object *ob_arm) +{ + return std::find(written_armatures.begin(), written_armatures.end(), ob_arm) != written_armatures.end(); +} + +void ArmatureExporter::wrote(Object *ob_arm) +{ + written_armatures.push_back(ob_arm); +} + +void ArmatureExporter::find_objects_using_armature(Object *ob_arm, std::vector& objects, Scene *sce) +{ + objects.clear(); + + Base *base= (Base*) sce->base.first; + while(base) { + Object *ob = base->object; + + if (ob->type == OB_MESH && get_assigned_armature(ob) == ob_arm) { + objects.push_back(ob); + } + + base= base->next; + } +} +#endif + +Object *ArmatureExporter::get_assigned_armature(Object *ob) +{ + Object *ob_arm = NULL; + + if (ob->parent && ob->partype == PARSKEL && ob->parent->type == OB_ARMATURE) { + ob_arm = ob->parent; + } + else { + ModifierData *mod = (ModifierData*)ob->modifiers.first; + while (mod) { + if (mod->type == eModifierType_Armature) { + ob_arm = ((ArmatureModifierData*)mod)->object; + } + + mod = mod->next; + } + } + + return ob_arm; +} + +std::string ArmatureExporter::get_joint_sid(Bone *bone, Object *ob_arm) +{ + return get_joint_id(bone, ob_arm); +} + +// parent_mat is armature-space +void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm) +{ + std::string node_id = get_joint_id(bone, ob_arm); + std::string node_name = std::string(bone->name); + std::string node_sid = get_joint_sid(bone, ob_arm); + + COLLADASW::Node node(mSW); + + node.setType(COLLADASW::Node::JOINT); + node.setNodeId(node_id); + node.setNodeName(node_name); + node.setNodeSid(node_sid); + + node.start(); + + add_bone_transform(ob_arm, bone, node); + + for (Bone *child = (Bone*)bone->childbase.first; child; child = child->next) { + add_bone_node(child, ob_arm); + } + + node.end(); +} + +void ArmatureExporter::add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node& node) +{ + bPoseChannel *pchan = get_pose_channel(ob_arm->pose, bone->name); + + float mat[4][4]; + + if (bone->parent) { + // get bone-space matrix from armature-space + bPoseChannel *parchan = get_pose_channel(ob_arm->pose, bone->parent->name); + + float invpar[4][4]; + invert_m4_m4(invpar, parchan->pose_mat); + mul_m4_m4m4(mat, pchan->pose_mat, invpar); + } + else { + // get world-space from armature-space + mul_m4_m4m4(mat, pchan->pose_mat, ob_arm->obmat); + } + + TransformWriter::add_node_transform(node, mat, NULL); +} + +std::string ArmatureExporter::get_controller_id(Object *ob_arm, Object *ob) +{ + return translate_id(id_name(ob_arm)) + "_" + translate_id(id_name(ob)) + SKIN_CONTROLLER_ID_SUFFIX; +} + +// ob should be of type OB_MESH +// both args are required +void ArmatureExporter::export_controller(Object* ob, Object *ob_arm) +{ + // joint names + // joint inverse bind matrices + // vertex weights + + // input: + // joint names: ob -> vertex group names + // vertex group weights: me->dvert -> groups -> index, weight + + /* + me->dvert: + + typedef struct MDeformVert { + struct MDeformWeight *dw; + int totweight; + int flag; // flag only in use for weightpaint now + } MDeformVert; + + typedef struct MDeformWeight { + int def_nr; + float weight; + } MDeformWeight; + */ + + Mesh *me = (Mesh*)ob->data; + if (!me->dvert) return; + + std::string controller_name = id_name(ob_arm); + std::string controller_id = get_controller_id(ob_arm, ob); + + openSkin(controller_id, controller_name, + COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, get_geometry_id(ob))); + + add_bind_shape_mat(ob); + + std::string joints_source_id = add_joints_source(ob_arm, &ob->defbase, controller_id); + std::string inv_bind_mat_source_id = add_inv_bind_mats_source(ob_arm, &ob->defbase, controller_id); + std::string weights_source_id = add_weights_source(me, controller_id); + + add_joints_element(&ob->defbase, joints_source_id, inv_bind_mat_source_id); + add_vertex_weights_element(weights_source_id, joints_source_id, me, ob_arm, &ob->defbase); + + closeSkin(); + closeController(); +} + +void ArmatureExporter::add_joints_element(ListBase *defbase, + const std::string& joints_source_id, const std::string& inv_bind_mat_source_id) +{ + COLLADASW::JointsElement joints(mSW); + COLLADASW::InputList &input = joints.getInputList(); + + input.push_back(COLLADASW::Input(COLLADASW::JOINT, // constant declared in COLLADASWInputList.h + COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, joints_source_id))); + input.push_back(COLLADASW::Input(COLLADASW::BINDMATRIX, + COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, inv_bind_mat_source_id))); + joints.add(); +} + +void ArmatureExporter::add_bind_shape_mat(Object *ob) +{ + double bind_mat[4][4]; + + converter.mat4_to_dae_double(bind_mat, ob->obmat); + + addBindShapeTransform(bind_mat); +} + +std::string ArmatureExporter::add_joints_source(Object *ob_arm, ListBase *defbase, const std::string& controller_id) +{ + std::string source_id = controller_id + JOINTS_SOURCE_ID_SUFFIX; + + int totjoint = 0; + bDeformGroup *def; + for (def = (bDeformGroup*)defbase->first; def; def = def->next) { + if (is_bone_defgroup(ob_arm, def)) + totjoint++; + } + + COLLADASW::NameSource source(mSW); + source.setId(source_id); + source.setArrayId(source_id + ARRAY_ID_SUFFIX); + source.setAccessorCount(totjoint); + source.setAccessorStride(1); + + COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); + param.push_back("JOINT"); + + source.prepareToAppendValues(); + + for (def = (bDeformGroup*)defbase->first; def; def = def->next) { + Bone *bone = get_bone_from_defgroup(ob_arm, def); + if (bone) + source.appendValues(get_joint_sid(bone, ob_arm)); + } + + source.finish(); + + return source_id; +} + +std::string ArmatureExporter::add_inv_bind_mats_source(Object *ob_arm, ListBase *defbase, const std::string& controller_id) +{ + std::string source_id = controller_id + BIND_POSES_SOURCE_ID_SUFFIX; + + COLLADASW::FloatSourceF source(mSW); + source.setId(source_id); + source.setArrayId(source_id + ARRAY_ID_SUFFIX); + source.setAccessorCount(BLI_countlist(defbase)); + source.setAccessorStride(16); + + source.setParameterTypeName(&COLLADASW::CSWC::CSW_VALUE_TYPE_FLOAT4x4); + COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); + param.push_back("TRANSFORM"); + + source.prepareToAppendValues(); + + bPose *pose = ob_arm->pose; + bArmature *arm = (bArmature*)ob_arm->data; + + int flag = arm->flag; + + // put armature in rest position + if (!(arm->flag & ARM_RESTPOS)) { + arm->flag |= ARM_RESTPOS; + where_is_pose(scene, ob_arm); + } + + for (bDeformGroup *def = (bDeformGroup*)defbase->first; def; def = def->next) { + if (is_bone_defgroup(ob_arm, def)) { + + bPoseChannel *pchan = get_pose_channel(pose, def->name); + + float mat[4][4]; + float world[4][4]; + float inv_bind_mat[4][4]; + + // make world-space matrix, pose_mat is armature-space + mul_m4_m4m4(world, pchan->pose_mat, ob_arm->obmat); + + invert_m4_m4(mat, world); + converter.mat4_to_dae(inv_bind_mat, mat); + + source.appendValues(inv_bind_mat); + } + } + + // back from rest positon + if (!(flag & ARM_RESTPOS)) { + arm->flag = flag; + where_is_pose(scene, ob_arm); + } + + source.finish(); + + return source_id; +} + +Bone *ArmatureExporter::get_bone_from_defgroup(Object *ob_arm, bDeformGroup* def) +{ + bPoseChannel *pchan = get_pose_channel(ob_arm->pose, def->name); + return pchan ? pchan->bone : NULL; +} + +bool ArmatureExporter::is_bone_defgroup(Object *ob_arm, bDeformGroup* def) +{ + return get_bone_from_defgroup(ob_arm, def) != NULL; +} + +std::string ArmatureExporter::add_weights_source(Mesh *me, const std::string& controller_id) +{ + std::string source_id = controller_id + WEIGHTS_SOURCE_ID_SUFFIX; + + int i; + int totweight = 0; + + for (i = 0; i < me->totvert; i++) { + totweight += me->dvert[i].totweight; + } + + COLLADASW::FloatSourceF source(mSW); + source.setId(source_id); + source.setArrayId(source_id + ARRAY_ID_SUFFIX); + source.setAccessorCount(totweight); + source.setAccessorStride(1); + + COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); + param.push_back("WEIGHT"); + + source.prepareToAppendValues(); + + // NOTE: COLLADA spec says weights should be normalized + + for (i = 0; i < me->totvert; i++) { + MDeformVert *vert = &me->dvert[i]; + for (int j = 0; j < vert->totweight; j++) { + source.appendValues(vert->dw[j].weight); + } + } + + source.finish(); + + return source_id; +} + +void ArmatureExporter::add_vertex_weights_element(const std::string& weights_source_id, const std::string& joints_source_id, Mesh *me, + Object *ob_arm, ListBase *defbase) +{ + COLLADASW::VertexWeightsElement weights(mSW); + COLLADASW::InputList &input = weights.getInputList(); + + int offset = 0; + input.push_back(COLLADASW::Input(COLLADASW::JOINT, // constant declared in COLLADASWInputList.h + COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, joints_source_id), offset++)); + input.push_back(COLLADASW::Input(COLLADASW::WEIGHT, + COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, weights_source_id), offset++)); + + weights.setCount(me->totvert); + + // write number of deformers per vertex + COLLADASW::PrimitivesBase::VCountList vcount; + int i; + for (i = 0; i < me->totvert; i++) { + vcount.push_back(me->dvert[i].totweight); + } + + weights.prepareToAppendVCountValues(); + weights.appendVertexCount(vcount); + + // def group index -> joint index + std::map joint_index_by_def_index; + bDeformGroup *def; + int j; + for (def = (bDeformGroup*)defbase->first, i = 0, j = 0; def; def = def->next, i++) { + if (is_bone_defgroup(ob_arm, def)) + joint_index_by_def_index[i] = j++; + else + joint_index_by_def_index[i] = -1; + } + + weights.CloseVCountAndOpenVElement(); + + // write deformer index - weight index pairs + int weight_index = 0; + for (i = 0; i < me->totvert; i++) { + MDeformVert *dvert = &me->dvert[i]; + for (int j = 0; j < dvert->totweight; j++) { + weights.appendValues(joint_index_by_def_index[dvert->dw[j].def_nr]); + weights.appendValues(weight_index++); + } + } + + weights.finish(); +} diff --git a/source/blender/collada/ArmatureExporter.h b/source/blender/collada/ArmatureExporter.h new file mode 100644 index 00000000000..fc3864a6c0f --- /dev/null +++ b/source/blender/collada/ArmatureExporter.h @@ -0,0 +1,137 @@ +/** + * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed, + * Nathan Letwory + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __ARMATUREEXPORTER_H__ +#define __ARMATUREEXPORTER_H__ + +#include +//#include + +#include "COLLADASWStreamWriter.h" +#include "COLLADASWLibraryControllers.h" +#include "COLLADASWInputList.h" +#include "COLLADASWNode.h" + +#include "DNA_armature_types.h" +#include "DNA_listBase.h" +#include "DNA_mesh_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "TransformWriter.h" +#include "InstanceWriter.h" + +// XXX exporter writes wrong data for shared armatures. A separate +// controller should be written for each armature-mesh binding how do +// we make controller ids then? +class ArmatureExporter: public COLLADASW::LibraryControllers, protected TransformWriter, protected InstanceWriter +{ +private: + Scene *scene; + +public: + ArmatureExporter(COLLADASW::StreamWriter *sw); + + // write bone nodes + void add_armature_bones(Object *ob_arm, Scene *sce); + + bool is_skinned_mesh(Object *ob); + + void add_instance_controller(Object *ob); + + void export_controllers(Scene *sce); + + void operator()(Object *ob); + +private: + + UnitConverter converter; + +#if 0 + std::vector written_armatures; + + bool already_written(Object *ob_arm); + + void wrote(Object *ob_arm); + + void find_objects_using_armature(Object *ob_arm, std::vector& objects, Scene *sce); +#endif + + Object *get_assigned_armature(Object *ob); + + std::string get_joint_sid(Bone *bone, Object *ob_arm); + + // parent_mat is armature-space + void add_bone_node(Bone *bone, Object *ob_arm); + + void add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node& node); + + std::string get_controller_id(Object *ob_arm, Object *ob); + + // ob should be of type OB_MESH + // both args are required + void export_controller(Object* ob, Object *ob_arm); + + void add_joints_element(ListBase *defbase, + const std::string& joints_source_id, const std::string& inv_bind_mat_source_id); + + void add_bind_shape_mat(Object *ob); + + std::string add_joints_source(Object *ob_arm, ListBase *defbase, const std::string& controller_id); + + std::string add_inv_bind_mats_source(Object *ob_arm, ListBase *defbase, const std::string& controller_id); + + Bone *get_bone_from_defgroup(Object *ob_arm, bDeformGroup* def); + + bool is_bone_defgroup(Object *ob_arm, bDeformGroup* def); + + std::string add_weights_source(Mesh *me, const std::string& controller_id); + + void add_vertex_weights_element(const std::string& weights_source_id, const std::string& joints_source_id, Mesh *me, + Object *ob_arm, ListBase *defbase); +}; + +/* +struct GeometryFunctor { + // f should have + // void operator()(Object* ob) + template + void forEachMeshObjectInScene(Scene *sce, Functor &f) + { + + Base *base= (Base*) sce->base.first; + while(base) { + Object *ob = base->object; + + if (ob->type == OB_MESH && ob->data) { + f(ob); + } + base= base->next; + + } + } +};*/ + +#endif diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp index 0a3166c37c3..ad85a81c6f8 100644 --- a/source/blender/collada/DocumentExporter.cpp +++ b/source/blender/collada/DocumentExporter.cpp @@ -34,8 +34,6 @@ extern "C" #include "DNA_image_types.h" #include "DNA_material_types.h" #include "DNA_texture_types.h" -//#include "DNA_camera_types.h" -//#include "DNA_lamp_types.h" #include "DNA_anim_types.h" #include "DNA_action_types.h" #include "DNA_curve_types.h" @@ -74,7 +72,6 @@ extern char build_rev[]; #include "COLLADASWAsset.h" #include "COLLADASWLibraryVisualScenes.h" #include "COLLADASWNode.h" -//#include "COLLADASWLibraryGeometries.h" #include "COLLADASWSource.h" #include "COLLADASWInstanceGeometry.h" #include "COLLADASWInputList.h" @@ -95,11 +92,8 @@ extern char build_rev[]; #include "COLLADASWTexture.h" #include "COLLADASWLibraryMaterials.h" #include "COLLADASWBindMaterial.h" -//#include "COLLADASWLibraryCameras.h" -//#include "COLLADASWLibraryLights.h" #include "COLLADASWInstanceCamera.h" #include "COLLADASWInstanceLight.h" -//#include "COLLADASWCameraOptic.h" #include "COLLADASWConstants.h" #include "COLLADASWLibraryControllers.h" #include "COLLADASWInstanceController.h" @@ -108,14 +102,19 @@ extern char build_rev[]; #include "collada_internal.h" #include "DocumentExporter.h" +#include "ArmatureExporter.h" #include "CameraExporter.h" -#include "LightExporter.h" #include "GeometryExporter.h" +#include "LightExporter.h" + +// can probably go after refactor is complete +#include "InstanceWriter.h" +#include "TransformWriter.h" #include #include // std::find -char *CustomData_get_layer_name(const struct CustomData *data, int type, int n) +char *bc_CustomData_get_layer_name(const struct CustomData *data, int type, int n) { int layer_index = CustomData_get_layer_index(data, type); if(layer_index < 0) return NULL; @@ -123,7 +122,7 @@ char *CustomData_get_layer_name(const struct CustomData *data, int type, int n) return data->layers[layer_index+n].name; } -char *CustomData_get_active_layer_name(const CustomData *data, int type) +char *bc_CustomData_get_active_layer_name(const CustomData *data, int type) { /* get the layer index of the active layer of type */ int layer_index = CustomData_get_active_layer_index(data, type); @@ -133,7 +132,6 @@ char *CustomData_get_active_layer_name(const CustomData *data, int type) } - /* Utilities to avoid code duplication. Definition can take some time to understand, but they should be useful. @@ -198,558 +196,11 @@ std::string getActiveUVLayerName(Object *ob) int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE); if (num_layers) - return std::string(CustomData_get_active_layer_name(&me->fdata, CD_MTFACE)); + return std::string(bc_CustomData_get_active_layer_name(&me->fdata, CD_MTFACE)); return ""; } - -class TransformWriter : protected TransformBase -{ -protected: - void add_node_transform(COLLADASW::Node& node, float mat[][4], float parent_mat[][4]) - { - float loc[3], rot[3], scale[3]; - float local[4][4]; - - if (parent_mat) { - float invpar[4][4]; - invert_m4_m4(invpar, parent_mat); - mul_m4_m4m4(local, mat, invpar); - } - else { - copy_m4_m4(local, mat); - } - - TransformBase::decompose(local, loc, rot, NULL, scale); - - add_transform(node, loc, rot, scale); - } - - void add_node_transform_ob(COLLADASW::Node& node, Object *ob) - { - float rot[3], loc[3], scale[3]; - - if (ob->parent) { - float C[4][4], tmat[4][4], imat[4][4], mat[4][4]; - - // factor out scale from obmat - - copy_v3_v3(scale, ob->size); - - ob->size[0] = ob->size[1] = ob->size[2] = 1.0f; - object_to_mat4(ob, C); - copy_v3_v3(ob->size, scale); - - mul_serie_m4(tmat, ob->parent->obmat, ob->parentinv, C, NULL, NULL, NULL, NULL, NULL); - - // calculate local mat - - invert_m4_m4(imat, ob->parent->obmat); - mul_m4_m4m4(mat, tmat, imat); - - // done - - mat4_to_eul(rot, mat); - copy_v3_v3(loc, mat[3]); - } - else { - copy_v3_v3(loc, ob->loc); - copy_v3_v3(rot, ob->rot); - copy_v3_v3(scale, ob->size); - } - - add_transform(node, loc, rot, scale); - } - - void add_node_transform_identity(COLLADASW::Node& node) - { - float loc[] = {0.0f, 0.0f, 0.0f}, scale[] = {1.0f, 1.0f, 1.0f}, rot[] = {0.0f, 0.0f, 0.0f}; - add_transform(node, loc, rot, scale); - } - -private: - void add_transform(COLLADASW::Node& node, float loc[3], float rot[3], float scale[3]) - { - node.addTranslate("location", loc[0], loc[1], loc[2]); - node.addRotateZ("rotationZ", COLLADABU::Math::Utils::radToDegF(rot[2])); - node.addRotateY("rotationY", COLLADABU::Math::Utils::radToDegF(rot[1])); - node.addRotateX("rotationX", COLLADABU::Math::Utils::radToDegF(rot[0])); - node.addScale("scale", scale[0], scale[1], scale[2]); - } -}; - -class InstanceWriter -{ -protected: - void add_material_bindings(COLLADASW::BindMaterial& bind_material, Object *ob) - { - for(int a = 0; a < ob->totcol; a++) { - Material *ma = give_current_material(ob, a+1); - - COLLADASW::InstanceMaterialList& iml = bind_material.getInstanceMaterialList(); - - if (ma) { - std::string matid(id_name(ma)); - matid = translate_id(matid); - COLLADASW::InstanceMaterial im(matid, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, matid)); - - // create for each uv layer - Mesh *me = (Mesh*)ob->data; - int totlayer = CustomData_number_of_layers(&me->fdata, CD_MTFACE); - - for (int b = 0; b < totlayer; b++) { - char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, b); - im.push_back(COLLADASW::BindVertexInput(name, "TEXCOORD", b)); - } - - iml.push_back(im); - } - } - } -}; - -// XXX exporter writes wrong data for shared armatures. A separate -// controller should be written for each armature-mesh binding how do -// we make controller ids then? -class ArmatureExporter: public COLLADASW::LibraryControllers, protected TransformWriter, protected InstanceWriter -{ -private: - Scene *scene; - -public: - ArmatureExporter(COLLADASW::StreamWriter *sw) : COLLADASW::LibraryControllers(sw) {} - - // write bone nodes - void add_armature_bones(Object *ob_arm, Scene *sce) - { - // write bone nodes - bArmature *arm = (bArmature*)ob_arm->data; - for (Bone *bone = (Bone*)arm->bonebase.first; bone; bone = bone->next) { - // start from root bones - if (!bone->parent) - add_bone_node(bone, ob_arm); - } - } - - bool is_skinned_mesh(Object *ob) - { - return get_assigned_armature(ob) != NULL; - } - - void add_instance_controller(Object *ob) - { - Object *ob_arm = get_assigned_armature(ob); - bArmature *arm = (bArmature*)ob_arm->data; - - const std::string& controller_id = get_controller_id(ob_arm, ob); - - COLLADASW::InstanceController ins(mSW); - ins.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, controller_id)); - - // write root bone URLs - Bone *bone; - for (bone = (Bone*)arm->bonebase.first; bone; bone = bone->next) { - if (!bone->parent) - ins.addSkeleton(COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, get_joint_id(bone, ob_arm))); - } - - InstanceWriter::add_material_bindings(ins.getBindMaterial(), ob); - - ins.add(); - } - - void export_controllers(Scene *sce) - { - scene = sce; - - openLibrary(); - - GeometryFunctor gf; - gf.forEachMeshObjectInScene(sce, *this); - - closeLibrary(); - } - - void operator()(Object *ob) - { - Object *ob_arm = get_assigned_armature(ob); - - if (ob_arm /*&& !already_written(ob_arm)*/) - export_controller(ob, ob_arm); - } - -private: - - UnitConverter converter; - -#if 0 - std::vector written_armatures; - - bool already_written(Object *ob_arm) - { - return std::find(written_armatures.begin(), written_armatures.end(), ob_arm) != written_armatures.end(); - } - - void wrote(Object *ob_arm) - { - written_armatures.push_back(ob_arm); - } - - void find_objects_using_armature(Object *ob_arm, std::vector& objects, Scene *sce) - { - objects.clear(); - - Base *base= (Base*) sce->base.first; - while(base) { - Object *ob = base->object; - - if (ob->type == OB_MESH && get_assigned_armature(ob) == ob_arm) { - objects.push_back(ob); - } - - base= base->next; - } - } -#endif - - Object *get_assigned_armature(Object *ob) - { - Object *ob_arm = NULL; - - if (ob->parent && ob->partype == PARSKEL && ob->parent->type == OB_ARMATURE) { - ob_arm = ob->parent; - } - else { - ModifierData *mod = (ModifierData*)ob->modifiers.first; - while (mod) { - if (mod->type == eModifierType_Armature) { - ob_arm = ((ArmatureModifierData*)mod)->object; - } - - mod = mod->next; - } - } - - return ob_arm; - } - - std::string get_joint_sid(Bone *bone, Object *ob_arm) - { - return get_joint_id(bone, ob_arm); - } - - // parent_mat is armature-space - void add_bone_node(Bone *bone, Object *ob_arm) - { - std::string node_id = get_joint_id(bone, ob_arm); - std::string node_name = std::string(bone->name); - std::string node_sid = get_joint_sid(bone, ob_arm); - - COLLADASW::Node node(mSW); - - node.setType(COLLADASW::Node::JOINT); - node.setNodeId(node_id); - node.setNodeName(node_name); - node.setNodeSid(node_sid); - - node.start(); - - add_bone_transform(ob_arm, bone, node); - - for (Bone *child = (Bone*)bone->childbase.first; child; child = child->next) { - add_bone_node(child, ob_arm); - } - - node.end(); - } - - void add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node& node) - { - bPoseChannel *pchan = get_pose_channel(ob_arm->pose, bone->name); - - float mat[4][4]; - - if (bone->parent) { - // get bone-space matrix from armature-space - bPoseChannel *parchan = get_pose_channel(ob_arm->pose, bone->parent->name); - - float invpar[4][4]; - invert_m4_m4(invpar, parchan->pose_mat); - mul_m4_m4m4(mat, pchan->pose_mat, invpar); - } - else { - // get world-space from armature-space - mul_m4_m4m4(mat, pchan->pose_mat, ob_arm->obmat); - } - - TransformWriter::add_node_transform(node, mat, NULL); - } - - std::string get_controller_id(Object *ob_arm, Object *ob) - { - return translate_id(id_name(ob_arm)) + "_" + translate_id(id_name(ob)) + SKIN_CONTROLLER_ID_SUFFIX; - } - - // ob should be of type OB_MESH - // both args are required - void export_controller(Object* ob, Object *ob_arm) - { - // joint names - // joint inverse bind matrices - // vertex weights - - // input: - // joint names: ob -> vertex group names - // vertex group weights: me->dvert -> groups -> index, weight - - /* - me->dvert: - - typedef struct MDeformVert { - struct MDeformWeight *dw; - int totweight; - int flag; // flag only in use for weightpaint now - } MDeformVert; - - typedef struct MDeformWeight { - int def_nr; - float weight; - } MDeformWeight; - */ - - Mesh *me = (Mesh*)ob->data; - if (!me->dvert) return; - - std::string controller_name = id_name(ob_arm); - std::string controller_id = get_controller_id(ob_arm, ob); - - openSkin(controller_id, controller_name, - COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, get_geometry_id(ob))); - - add_bind_shape_mat(ob); - - std::string joints_source_id = add_joints_source(ob_arm, &ob->defbase, controller_id); - std::string inv_bind_mat_source_id = add_inv_bind_mats_source(ob_arm, &ob->defbase, controller_id); - std::string weights_source_id = add_weights_source(me, controller_id); - - add_joints_element(&ob->defbase, joints_source_id, inv_bind_mat_source_id); - add_vertex_weights_element(weights_source_id, joints_source_id, me, ob_arm, &ob->defbase); - - closeSkin(); - closeController(); - } - - void add_joints_element(ListBase *defbase, - const std::string& joints_source_id, const std::string& inv_bind_mat_source_id) - { - COLLADASW::JointsElement joints(mSW); - COLLADASW::InputList &input = joints.getInputList(); - - input.push_back(COLLADASW::Input(COLLADASW::JOINT, // constant declared in COLLADASWInputList.h - COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, joints_source_id))); - input.push_back(COLLADASW::Input(COLLADASW::BINDMATRIX, - COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, inv_bind_mat_source_id))); - joints.add(); - } - - void add_bind_shape_mat(Object *ob) - { - double bind_mat[4][4]; - - converter.mat4_to_dae_double(bind_mat, ob->obmat); - - addBindShapeTransform(bind_mat); - } - - std::string add_joints_source(Object *ob_arm, ListBase *defbase, const std::string& controller_id) - { - std::string source_id = controller_id + JOINTS_SOURCE_ID_SUFFIX; - - int totjoint = 0; - bDeformGroup *def; - for (def = (bDeformGroup*)defbase->first; def; def = def->next) { - if (is_bone_defgroup(ob_arm, def)) - totjoint++; - } - - COLLADASW::NameSource source(mSW); - source.setId(source_id); - source.setArrayId(source_id + ARRAY_ID_SUFFIX); - source.setAccessorCount(totjoint); - source.setAccessorStride(1); - - COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); - param.push_back("JOINT"); - - source.prepareToAppendValues(); - - for (def = (bDeformGroup*)defbase->first; def; def = def->next) { - Bone *bone = get_bone_from_defgroup(ob_arm, def); - if (bone) - source.appendValues(get_joint_sid(bone, ob_arm)); - } - - source.finish(); - - return source_id; - } - - std::string add_inv_bind_mats_source(Object *ob_arm, ListBase *defbase, const std::string& controller_id) - { - std::string source_id = controller_id + BIND_POSES_SOURCE_ID_SUFFIX; - - COLLADASW::FloatSourceF source(mSW); - source.setId(source_id); - source.setArrayId(source_id + ARRAY_ID_SUFFIX); - source.setAccessorCount(BLI_countlist(defbase)); - source.setAccessorStride(16); - - source.setParameterTypeName(&COLLADASW::CSWC::CSW_VALUE_TYPE_FLOAT4x4); - COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); - param.push_back("TRANSFORM"); - - source.prepareToAppendValues(); - - bPose *pose = ob_arm->pose; - bArmature *arm = (bArmature*)ob_arm->data; - - int flag = arm->flag; - - // put armature in rest position - if (!(arm->flag & ARM_RESTPOS)) { - arm->flag |= ARM_RESTPOS; - where_is_pose(scene, ob_arm); - } - - for (bDeformGroup *def = (bDeformGroup*)defbase->first; def; def = def->next) { - if (is_bone_defgroup(ob_arm, def)) { - - bPoseChannel *pchan = get_pose_channel(pose, def->name); - - float mat[4][4]; - float world[4][4]; - float inv_bind_mat[4][4]; - - // make world-space matrix, pose_mat is armature-space - mul_m4_m4m4(world, pchan->pose_mat, ob_arm->obmat); - - invert_m4_m4(mat, world); - converter.mat4_to_dae(inv_bind_mat, mat); - - source.appendValues(inv_bind_mat); - } - } - - // back from rest positon - if (!(flag & ARM_RESTPOS)) { - arm->flag = flag; - where_is_pose(scene, ob_arm); - } - - source.finish(); - - return source_id; - } - - Bone *get_bone_from_defgroup(Object *ob_arm, bDeformGroup* def) - { - bPoseChannel *pchan = get_pose_channel(ob_arm->pose, def->name); - return pchan ? pchan->bone : NULL; - } - - bool is_bone_defgroup(Object *ob_arm, bDeformGroup* def) - { - return get_bone_from_defgroup(ob_arm, def) != NULL; - } - - std::string add_weights_source(Mesh *me, const std::string& controller_id) - { - std::string source_id = controller_id + WEIGHTS_SOURCE_ID_SUFFIX; - - int i; - int totweight = 0; - - for (i = 0; i < me->totvert; i++) { - totweight += me->dvert[i].totweight; - } - - COLLADASW::FloatSourceF source(mSW); - source.setId(source_id); - source.setArrayId(source_id + ARRAY_ID_SUFFIX); - source.setAccessorCount(totweight); - source.setAccessorStride(1); - - COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); - param.push_back("WEIGHT"); - - source.prepareToAppendValues(); - - // NOTE: COLLADA spec says weights should be normalized - - for (i = 0; i < me->totvert; i++) { - MDeformVert *vert = &me->dvert[i]; - for (int j = 0; j < vert->totweight; j++) { - source.appendValues(vert->dw[j].weight); - } - } - - source.finish(); - - return source_id; - } - - void add_vertex_weights_element(const std::string& weights_source_id, const std::string& joints_source_id, Mesh *me, - Object *ob_arm, ListBase *defbase) - { - COLLADASW::VertexWeightsElement weights(mSW); - COLLADASW::InputList &input = weights.getInputList(); - - int offset = 0; - input.push_back(COLLADASW::Input(COLLADASW::JOINT, // constant declared in COLLADASWInputList.h - COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, joints_source_id), offset++)); - input.push_back(COLLADASW::Input(COLLADASW::WEIGHT, - COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, weights_source_id), offset++)); - - weights.setCount(me->totvert); - - // write number of deformers per vertex - COLLADASW::PrimitivesBase::VCountList vcount; - int i; - for (i = 0; i < me->totvert; i++) { - vcount.push_back(me->dvert[i].totweight); - } - - weights.prepareToAppendVCountValues(); - weights.appendVertexCount(vcount); - - // def group index -> joint index - std::map joint_index_by_def_index; - bDeformGroup *def; - int j; - for (def = (bDeformGroup*)defbase->first, i = 0, j = 0; def; def = def->next, i++) { - if (is_bone_defgroup(ob_arm, def)) - joint_index_by_def_index[i] = j++; - else - joint_index_by_def_index[i] = -1; - } - - weights.CloseVCountAndOpenVElement(); - - // write deformer index - weight index pairs - int weight_index = 0; - for (i = 0; i < me->totvert; i++) { - MDeformVert *dvert = &me->dvert[i]; - for (int j = 0; j < dvert->totweight; j++) { - weights.appendValues(joint_index_by_def_index[dvert->dw[j].def_nr]); - weights.appendValues(weight_index++); - } - } - - weights.finish(); - } -}; - class SceneExporter: COLLADASW::LibraryVisualScenes, protected TransformWriter, protected InstanceWriter { ArmatureExporter *arm_exporter; diff --git a/source/blender/collada/InstanceWriter.cpp b/source/blender/collada/InstanceWriter.cpp new file mode 100644 index 00000000000..a3260c85f68 --- /dev/null +++ b/source/blender/collada/InstanceWriter.cpp @@ -0,0 +1,64 @@ +/** + * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed, + * Nathan Letwory + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include + +#include "COLLADASWInstanceMaterial.h" + +#include "BKE_customdata.h" +#include "BKE_material.h" + +#include "DNA_mesh_types.h" + +#include "InstanceWriter.h" + +#include "collada_internal.h" +#include "collada_utils.h" + +void InstanceWriter::add_material_bindings(COLLADASW::BindMaterial& bind_material, Object *ob) +{ + for(int a = 0; a < ob->totcol; a++) { + Material *ma = give_current_material(ob, a+1); + + COLLADASW::InstanceMaterialList& iml = bind_material.getInstanceMaterialList(); + + if (ma) { + std::string matid(id_name(ma)); + matid = translate_id(matid); + COLLADASW::InstanceMaterial im(matid, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, matid)); + + // create for each uv layer + Mesh *me = (Mesh*)ob->data; + int totlayer = CustomData_number_of_layers(&me->fdata, CD_MTFACE); + + for (int b = 0; b < totlayer; b++) { + char *name = bc_CustomData_get_layer_name(&me->fdata, CD_MTFACE, b); + im.push_back(COLLADASW::BindVertexInput(name, "TEXCOORD", b)); + } + + iml.push_back(im); + } + } +} diff --git a/source/blender/collada/InstanceWriter.h b/source/blender/collada/InstanceWriter.h new file mode 100644 index 00000000000..f7585bb20db --- /dev/null +++ b/source/blender/collada/InstanceWriter.h @@ -0,0 +1,39 @@ +/** + * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed, + * Nathan Letwory + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __INSTANCEWRITER_H__ +#define __INSTANCEWRITER_H__ + +#include "COLLADASWBindMaterial.h" + +#include "DNA_object_types.h" + +class InstanceWriter +{ +protected: + void add_material_bindings(COLLADASW::BindMaterial& bind_material, Object *ob); +}; + +#endif diff --git a/source/blender/collada/TransformWriter.cpp b/source/blender/collada/TransformWriter.cpp new file mode 100644 index 00000000000..21260a2d4f1 --- /dev/null +++ b/source/blender/collada/TransformWriter.cpp @@ -0,0 +1,100 @@ +/** + * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed, + * Nathan Letwory + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "BKE_object.h" + +#include "TransformWriter.h" + +#include "BLI_math.h" + +void TransformWriter::add_node_transform(COLLADASW::Node& node, float mat[][4], float parent_mat[][4]) +{ + float loc[3], rot[3], scale[3]; + float local[4][4]; + + if (parent_mat) { + float invpar[4][4]; + invert_m4_m4(invpar, parent_mat); + mul_m4_m4m4(local, mat, invpar); + } + else { + copy_m4_m4(local, mat); + } + + TransformBase::decompose(local, loc, rot, NULL, scale); + + add_transform(node, loc, rot, scale); +} + +void TransformWriter::add_node_transform_ob(COLLADASW::Node& node, Object *ob) +{ + float rot[3], loc[3], scale[3]; + + if (ob->parent) { + float C[4][4], tmat[4][4], imat[4][4], mat[4][4]; + + // factor out scale from obmat + + copy_v3_v3(scale, ob->size); + + ob->size[0] = ob->size[1] = ob->size[2] = 1.0f; + object_to_mat4(ob, C); + copy_v3_v3(ob->size, scale); + + mul_serie_m4(tmat, ob->parent->obmat, ob->parentinv, C, NULL, NULL, NULL, NULL, NULL); + + // calculate local mat + + invert_m4_m4(imat, ob->parent->obmat); + mul_m4_m4m4(mat, tmat, imat); + + // done + + mat4_to_eul(rot, mat); + copy_v3_v3(loc, mat[3]); + } + else { + copy_v3_v3(loc, ob->loc); + copy_v3_v3(rot, ob->rot); + copy_v3_v3(scale, ob->size); + } + + add_transform(node, loc, rot, scale); +} + +void TransformWriter::add_node_transform_identity(COLLADASW::Node& node) +{ + float loc[] = {0.0f, 0.0f, 0.0f}, scale[] = {1.0f, 1.0f, 1.0f}, rot[] = {0.0f, 0.0f, 0.0f}; + add_transform(node, loc, rot, scale); +} + +void TransformWriter::add_transform(COLLADASW::Node& node, float loc[3], float rot[3], float scale[3]) +{ + node.addTranslate("location", loc[0], loc[1], loc[2]); + node.addRotateZ("rotationZ", COLLADABU::Math::Utils::radToDegF(rot[2])); + node.addRotateY("rotationY", COLLADABU::Math::Utils::radToDegF(rot[1])); + node.addRotateX("rotationX", COLLADABU::Math::Utils::radToDegF(rot[0])); + node.addScale("scale", scale[0], scale[1], scale[2]); +} diff --git a/source/blender/collada/TransformWriter.h b/source/blender/collada/TransformWriter.h new file mode 100644 index 00000000000..29aef721afb --- /dev/null +++ b/source/blender/collada/TransformWriter.h @@ -0,0 +1,48 @@ +/** + * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed, + * Nathan Letwory + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __TRANSFORMWRITER_H__ +#define __TRANSFORMWRITER_H__ + +#include "COLLADASWNode.h" + +#include "DNA_object_types.h" + +#include "collada_internal.h" + +class TransformWriter : protected TransformBase +{ +protected: + void add_node_transform(COLLADASW::Node& node, float mat[][4], float parent_mat[][4]); + + void add_node_transform_ob(COLLADASW::Node& node, Object *ob); + + void add_node_transform_identity(COLLADASW::Node& node); + +private: + void add_transform(COLLADASW::Node& node, float loc[3], float rot[3], float scale[3]); +}; + +#endif -- cgit v1.2.3 From e161c22dc24842e1900f3c68948fe7a4af973c4e Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Wed, 6 Oct 2010 12:04:56 +0000 Subject: Assorted GCC fixes for OpenCOLLADA support --- source/blender/collada/ArmatureExporter.cpp | 2 +- source/blender/collada/DocumentExporter.cpp | 2 +- source/blender/collada/MeshImporter.cpp | 6 +++++- source/blender/collada/SkinInfo.cpp | 4 ++++ 4 files changed, 11 insertions(+), 3 deletions(-) (limited to 'source/blender') diff --git a/source/blender/collada/ArmatureExporter.cpp b/source/blender/collada/ArmatureExporter.cpp index 527ccd66577..bf75baaf89d 100644 --- a/source/blender/collada/ArmatureExporter.cpp +++ b/source/blender/collada/ArmatureExporter.cpp @@ -35,7 +35,7 @@ #include "BKE_action.h" #include "BKE_armature.h" -#include "BLI_listBase.h" +#include "BLI_listbase.h" #include "GeometryExporter.h" #include "ArmatureExporter.h" diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp index ad85a81c6f8..914c8a656f9 100644 --- a/source/blender/collada/DocumentExporter.cpp +++ b/source/blender/collada/DocumentExporter.cpp @@ -186,7 +186,7 @@ void forEachMaterialInScene(Scene *sce, Functor &f) { ForEachMaterialFunctor matfunc(&f); GeometryFunctor gf; - gf.forEachMeshObjectInScene>(sce, matfunc); + gf.forEachMeshObjectInScene >(sce, matfunc); } // OB_MESH is assumed diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp index 34da6c9e897..df5136f1cb4 100644 --- a/source/blender/collada/MeshImporter.cpp +++ b/source/blender/collada/MeshImporter.cpp @@ -24,6 +24,10 @@ #include +#ifndef WIN32 +#include +#endif + #include "COLLADAFWMeshPrimitive.h" #include "COLLADAFWMeshVertexData.h" #include "COLLADAFWPolygons.h" @@ -904,4 +908,4 @@ bool MeshImporter::write_geometry(const COLLADAFW::Geometry* geom) mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); return true; -} \ No newline at end of file +} diff --git a/source/blender/collada/SkinInfo.cpp b/source/blender/collada/SkinInfo.cpp index 58985d58db3..a3ac6a30c59 100644 --- a/source/blender/collada/SkinInfo.cpp +++ b/source/blender/collada/SkinInfo.cpp @@ -24,6 +24,10 @@ #include +#ifndef WIN32 +#include +#endif + #include "BKE_object.h" #include "DNA_armature_types.h" #include "DNA_modifier_types.h" -- cgit v1.2.3 From 0d815d3528912eede6ee90f3a12435cbcca1eb04 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Wed, 6 Oct 2010 13:21:08 +0000 Subject: COLLADA: Split MaterialsExporter into separate files. --- source/blender/collada/DocumentExporter.cpp | 70 ++--------------------- source/blender/collada/MaterialExporter.cpp | 55 ++++++++++++++++++ source/blender/collada/MaterialExporter.h | 88 +++++++++++++++++++++++++++++ 3 files changed, 148 insertions(+), 65 deletions(-) create mode 100644 source/blender/collada/MaterialExporter.cpp create mode 100644 source/blender/collada/MaterialExporter.h (limited to 'source/blender') diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp index 914c8a656f9..f93a8ef72cd 100644 --- a/source/blender/collada/DocumentExporter.cpp +++ b/source/blender/collada/DocumentExporter.cpp @@ -106,6 +106,7 @@ extern char build_rev[]; #include "CameraExporter.h" #include "GeometryExporter.h" #include "LightExporter.h" +#include "MaterialExporter.h" // can probably go after refactor is complete #include "InstanceWriter.h" @@ -151,43 +152,7 @@ void forEachObjectInScene(Scene *sce, Functor &f) } } -// used in forEachMaterialInScene -template -class ForEachMaterialFunctor -{ - std::vector mMat; // contains list of material names, to avoid duplicate calling of f - MaterialFunctor *f; -public: - ForEachMaterialFunctor(MaterialFunctor *f) : f(f) { } - void operator ()(Object *ob) - { - int a; - for(a = 0; a < ob->totcol; a++) { - - Material *ma = give_current_material(ob, a+1); - if (!ma) continue; - - std::string translated_id = translate_id(id_name(ma)); - if (find(mMat.begin(), mMat.end(), translated_id) == mMat.end()) { - (*this->f)(ma, ob); - - mMat.push_back(translated_id); - } - } - } -}; - -// calls f for each unique material linked to each object in sce -// f should have -// void operator()(Material* ma) -template -void forEachMaterialInScene(Scene *sce, Functor &f) -{ - ForEachMaterialFunctor matfunc(&f); - GeometryFunctor gf; - gf.forEachMeshObjectInScene >(sce, matfunc); -} // OB_MESH is assumed std::string getActiveUVLayerName(Object *ob) @@ -344,8 +309,8 @@ public: void exportImages(Scene *sce) { openLibrary(); - - forEachMaterialInScene(sce, *this); + MaterialFunctor mf; + mf.forEachMaterialInScene(sce, *this); closeLibrary(); } @@ -401,8 +366,8 @@ public: void exportEffects(Scene *sce) { openLibrary(); - - forEachMaterialInScene(sce, *this); + MaterialFunctor mf; + mf.forEachMaterialInScene(sce, *this); closeLibrary(); } @@ -652,31 +617,6 @@ public: } }; -class MaterialsExporter: COLLADASW::LibraryMaterials -{ -public: - MaterialsExporter(COLLADASW::StreamWriter *sw): COLLADASW::LibraryMaterials(sw){} - void exportMaterials(Scene *sce) - { - openLibrary(); - - forEachMaterialInScene(sce, *this); - - closeLibrary(); - } - - void operator()(Material *ma, Object *ob) - { - std::string name(id_name(ma)); - - openMaterial(translate_id(name), name); - - std::string efid = translate_id(name) + "-effect"; - addInstanceEffect(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, efid)); - - closeMaterial(); - } -}; // TODO: it would be better to instantiate animations rather than create a new one per object // COLLADA allows this through multiple s in . diff --git a/source/blender/collada/MaterialExporter.cpp b/source/blender/collada/MaterialExporter.cpp new file mode 100644 index 00000000000..e873227745c --- /dev/null +++ b/source/blender/collada/MaterialExporter.cpp @@ -0,0 +1,55 @@ +/** + * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed, + * Nathan Letwory + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "COLLADABUUtils.h" + +#include "BKE_material.h" + +#include "MaterialExporter.h" +#include "collada_internal.h" + +MaterialsExporter::MaterialsExporter(COLLADASW::StreamWriter *sw): COLLADASW::LibraryMaterials(sw){} + +void MaterialsExporter::exportMaterials(Scene *sce) +{ + openLibrary(); + + MaterialFunctor mf; + mf.forEachMaterialInScene(sce, *this); + + closeLibrary(); +} + +void MaterialsExporter::operator()(Material *ma, Object *ob) +{ + std::string name(id_name(ma)); + + openMaterial(translate_id(name), name); + + std::string efid = translate_id(name) + "-effect"; + addInstanceEffect(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, efid)); + + closeMaterial(); +} diff --git a/source/blender/collada/MaterialExporter.h b/source/blender/collada/MaterialExporter.h new file mode 100644 index 00000000000..35aaaad43fd --- /dev/null +++ b/source/blender/collada/MaterialExporter.h @@ -0,0 +1,88 @@ +/** + * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed, + * Nathan Letwory + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __MATERIALEXPORTER_H__ +#define __MATERIALEXPORTER_H__ + +#include "COLLADASWLibraryMaterials.h" +#include "COLLADASWStreamWriter.h" + +#include "DNA_material_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "GeometryExporter.h" + +class MaterialsExporter: COLLADASW::LibraryMaterials +{ +public: + MaterialsExporter(COLLADASW::StreamWriter *sw); + void exportMaterials(Scene *sce); + void operator()(Material *ma, Object *ob); +}; + +// used in forEachMaterialInScene +template +class ForEachMaterialFunctor +{ + std::vector mMat; // contains list of material names, to avoid duplicate calling of f + Functor *f; +public: + ForEachMaterialFunctor(Functor*f) : f(f) {} + + void operator ()(Object *ob) + { + int a; + for(a = 0; a < ob->totcol; a++) { + + Material *ma = give_current_material(ob, a+1); + + if (!ma) continue; + + std::string translated_id = translate_id(id_name(ma)); + if (find(mMat.begin(), mMat.end(), translated_id) == mMat.end()) { + (*this->f)(ma, ob); + + mMat.push_back(translated_id); + } + } + } +}; + +struct MaterialFunctor { + // calls f for each unique material linked to each object in sce + // f should have + // void operator()(Material* ma) + template + void forEachMaterialInScene(Scene *sce, Functor &f) + { + ForEachMaterialFunctor matfunc(&f); + GeometryFunctor gf; + gf.forEachMeshObjectInScene >(sce, matfunc); + } +}; + + +#endif -- cgit v1.2.3 From ca44eb3abd4ac2729c0d276b561ed2d3b49efe3f Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Wed, 6 Oct 2010 13:55:50 +0000 Subject: GCC fixes for r32346 --- source/blender/collada/DocumentExporter.cpp | 7 ++++--- source/blender/collada/MaterialExporter.cpp | 2 -- source/blender/collada/MaterialExporter.h | 6 ++++++ 3 files changed, 10 insertions(+), 5 deletions(-) (limited to 'source/blender') diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp index f93a8ef72cd..06df94416b3 100644 --- a/source/blender/collada/DocumentExporter.cpp +++ b/source/blender/collada/DocumentExporter.cpp @@ -102,15 +102,16 @@ extern char build_rev[]; #include "collada_internal.h" #include "DocumentExporter.h" +// can probably go after refactor is complete +#include "InstanceWriter.h" +#include "TransformWriter.h" + #include "ArmatureExporter.h" #include "CameraExporter.h" #include "GeometryExporter.h" #include "LightExporter.h" #include "MaterialExporter.h" -// can probably go after refactor is complete -#include "InstanceWriter.h" -#include "TransformWriter.h" #include #include // std::find diff --git a/source/blender/collada/MaterialExporter.cpp b/source/blender/collada/MaterialExporter.cpp index e873227745c..66ebe2d9ed8 100644 --- a/source/blender/collada/MaterialExporter.cpp +++ b/source/blender/collada/MaterialExporter.cpp @@ -25,8 +25,6 @@ #include "COLLADABUUtils.h" -#include "BKE_material.h" - #include "MaterialExporter.h" #include "collada_internal.h" diff --git a/source/blender/collada/MaterialExporter.h b/source/blender/collada/MaterialExporter.h index 35aaaad43fd..972cd8bd8e5 100644 --- a/source/blender/collada/MaterialExporter.h +++ b/source/blender/collada/MaterialExporter.h @@ -26,14 +26,20 @@ #ifndef __MATERIALEXPORTER_H__ #define __MATERIALEXPORTER_H__ +#include +#include + #include "COLLADASWLibraryMaterials.h" #include "COLLADASWStreamWriter.h" +#include "BKE_material.h" + #include "DNA_material_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "GeometryExporter.h" +#include "collada_internal.h" class MaterialsExporter: COLLADASW::LibraryMaterials { -- cgit v1.2.3 From d256ec9d2405416c7a8a26862fa2196f13dabb6b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 6 Oct 2010 14:17:28 +0000 Subject: bugfix [#23311] Half a colour picker appears all popups which are positioned based on an existing button are now clamped to window bounds. --- source/blender/editors/interface/interface_regions.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source/blender') diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 50b85360196..ff079a4b9e0 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -1116,6 +1116,7 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, if(but) { int left=0, right=0, top=0, down=0; int winx, winy; + int offscreen; wm_window_get_size(window, &winx, &winy); @@ -1206,6 +1207,12 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, // apply requested offset in the block xof += block->xofs/block->aspect; yof += block->yofs/block->aspect; + + /* clamp to window bounds, could be made into an option if its ever annoying */ + if( (offscreen= (block->miny+yof)) < 0) yof -= offscreen; /* bottom */ + else if((offscreen= (block->maxy+yof)-winy) > 0) yof -= offscreen; /* top */ + if( (offscreen= (block->minx+xof)) < 0) xof -= offscreen; /* left */ + else if((offscreen= (block->maxx+xof)-winx) > 0) xof -= offscreen; /* right */ } /* apply */ -- cgit v1.2.3 From 61d23ff95b71eb71bf7ced09f410ab1acc9a6db4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 6 Oct 2010 14:47:40 +0000 Subject: minor edits so traceray() uses less stack memory, also remove memset() usage, initialize as {0}. no functional change. --- source/blender/render/intern/source/rayshade.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) (limited to 'source/blender') diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 724fd9a3110..1172bee7d67 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -697,17 +697,9 @@ static void ray_fadeout(Isect *is, ShadeInput *shi, float *col, float *blendcol, * note: 'col' must be initialized */ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, float *start, float *vec, float *col, ObjectInstanceRen *obi, VlakRen *vlr, int traflag) { - ShadeInput shi; - ShadeResult shr; + ShadeInput shi= {0}; Isect isec; - float f, f1, fr, fg, fb; - float ref[3]; float dist_mir = origshi->mat->dist_mir; - - /* Warning, This is not that nice, and possibly a bit slow for every ray, - however some variables were not initialized properly in, unless using shade_input_initialize(...), we need to do a memset */ - memset(&shi, 0, sizeof(ShadeInput)); - /* end warning! - Campbell */ VECCOPY(isec.start, start); VECCOPY(isec.vec, vec ); @@ -721,8 +713,9 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, flo RE_RC_INIT(isec, shi); if(RE_rayobject_raycast(R.raytree, &isec)) { + ShadeResult shr= {{0}}; float d= 1.0f; - + shi.mask= origshi->mask; shi.osatex= origshi->osatex; shi.depth= 1; /* only used to indicate tracing */ @@ -737,16 +730,15 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, flo shi.light_override= origshi->light_override; shi.mat_override= origshi->mat_override; - memset(&shr, 0, sizeof(ShadeResult)); - shade_ray(&isec, &shi, &shr); if (traflag & RAY_TRA) d= shade_by_transmission(&isec, &shi, &shr); if(depth>0) { + float fr, fg, fb, f, f1; if((shi.mat->mode_l & MA_TRANSP) && shr.alpha < 1.0f) { - float nf, f, f1, refract[3], tracol[4]; + float nf, f, refract[3], tracol[4]; tracol[0]= shi.r; tracol[1]= shi.g; @@ -799,6 +791,7 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, flo if(f!=0.0f) { float mircol[4]; + float ref[3]; reflection(ref, shi.vn, shi.view, NULL); traceray(origshi, origshr, depth-1, shi.co, ref, mircol, shi.obi, shi.vlr, 0); -- cgit v1.2.3 From 352fbb154978fbcc6b01440df37a3447400e8364 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 6 Oct 2010 14:53:13 +0000 Subject: remove unused vol_get_density() call. --- source/blender/render/intern/source/volumetric.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source/blender') diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c index a58d96736d5..d15ea0c792c 100644 --- a/source/blender/render/intern/source/volumetric.c +++ b/source/blender/render/intern/source/volumetric.c @@ -743,7 +743,6 @@ void shade_volume_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct float tr[3] = {1.0,1.0,1.0}; Isect is; float *startco, *endco; - float density=0.f; memset(shr, 0, sizeof(ShadeResult)); @@ -764,8 +763,7 @@ void shade_volume_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct shr->alpha = shr->combined[3] = 1.f; return; } - - density = vol_get_density(shi, startco); + vol_get_transmittance(shi, tr, startco, endco); copy_v3_v3(shr->combined, tr); -- cgit v1.2.3 From c0b36a0be0474c5bd3a4859450d257099c8fe681 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Wed, 6 Oct 2010 16:23:52 +0000 Subject: COLLADA: Split ImagesExporter into separate files. --- source/blender/blenlib/BLI_fileops.h | 8 +++ source/blender/collada/DocumentExporter.cpp | 63 +------------------ source/blender/collada/ImageExporter.cpp | 93 +++++++++++++++++++++++++++++ source/blender/collada/ImageExporter.h | 50 ++++++++++++++++ 4 files changed, 152 insertions(+), 62 deletions(-) create mode 100644 source/blender/collada/ImageExporter.cpp create mode 100644 source/blender/collada/ImageExporter.h (limited to 'source/blender') diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h index 6c98d30e4b1..b721a21b1b9 100644 --- a/source/blender/blenlib/BLI_fileops.h +++ b/source/blender/blenlib/BLI_fileops.h @@ -36,6 +36,10 @@ #ifndef BLI_FILEOPS_H #define BLI_FILEOPS_H +#ifdef __cplusplus +extern "C" { +#endif + void BLI_recurdir_fileops(char *dirname); int BLI_link(char *file, char *to); int BLI_is_writable(char *filename); @@ -60,5 +64,9 @@ char *first_slash(char *string); void BLI_setCmdCallBack(int (*f)(char*)); #endif +#ifdef __cplusplus +} +#endif + #endif diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp index 06df94416b3..9bf84c7e606 100644 --- a/source/blender/collada/DocumentExporter.cpp +++ b/source/blender/collada/DocumentExporter.cpp @@ -109,10 +109,10 @@ extern char build_rev[]; #include "ArmatureExporter.h" #include "CameraExporter.h" #include "GeometryExporter.h" +#include "ImageExporter.h" #include "LightExporter.h" #include "MaterialExporter.h" - #include #include // std::find @@ -299,67 +299,6 @@ public: } }; -class ImagesExporter: COLLADASW::LibraryImages -{ - const char *mfilename; - std::vector mImages; // contains list of written images, to avoid duplicates -public: - ImagesExporter(COLLADASW::StreamWriter *sw, const char* filename) : COLLADASW::LibraryImages(sw), mfilename(filename) - {} - - void exportImages(Scene *sce) - { - openLibrary(); - MaterialFunctor mf; - mf.forEachMaterialInScene(sce, *this); - - closeLibrary(); - } - - void operator()(Material *ma, Object *ob) - { - int a; - for (a = 0; a < MAX_MTEX; a++) { - MTex *mtex = ma->mtex[a]; - if (mtex && mtex->tex && mtex->tex->ima) { - - Image *image = mtex->tex->ima; - std::string name(id_name(image)); - name = translate_id(name); - char rel[FILE_MAX]; - char abs[FILE_MAX]; - char src[FILE_MAX]; - char dir[FILE_MAX]; - - BLI_split_dirfile(mfilename, dir, NULL); - - BKE_rebase_path(abs, sizeof(abs), rel, sizeof(rel), G.sce, image->name, dir); - - if (abs[0] != '\0') { - - // make absolute source path - BLI_strncpy(src, image->name, sizeof(src)); - BLI_path_abs(src, G.sce); - - // make dest directory if it doesn't exist - BLI_make_existing_file(abs); - - if (BLI_copy_fileops(src, abs) != 0) { - fprintf(stderr, "Cannot copy image to file's directory. \n"); - } - } - - if (find(mImages.begin(), mImages.end(), name) == mImages.end()) { - COLLADASW::Image img(COLLADABU::URI(COLLADABU::URI::nativePathToUri(rel)), name); - img.add(mSW); - - mImages.push_back(name); - } - } - } - } -}; - class EffectsExporter: COLLADASW::LibraryEffects { public: diff --git a/source/blender/collada/ImageExporter.cpp b/source/blender/collada/ImageExporter.cpp new file mode 100644 index 00000000000..3bcce313aa5 --- /dev/null +++ b/source/blender/collada/ImageExporter.cpp @@ -0,0 +1,93 @@ +/** + * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed, + * Nathan Letwory + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "COLLADABUURI.h" +#include "COLLADASWImage.h" + +#include "ImageExporter.h" +#include "MaterialExporter.h" + +#include "DNA_texture_types.h" + +#include "BKE_global.h" +#include "BKE_utildefines.h" +#include "BLI_fileops.h" +#include "BLI_path_util.h" +#include "BLI_string.h" + +ImagesExporter::ImagesExporter(COLLADASW::StreamWriter *sw, const char* filename) : COLLADASW::LibraryImages(sw), mfilename(filename) +{} + +void ImagesExporter::exportImages(Scene *sce) +{ + openLibrary(); + MaterialFunctor mf; + mf.forEachMaterialInScene(sce, *this); + + closeLibrary(); +} + +void ImagesExporter::operator()(Material *ma, Object *ob) +{ + int a; + for (a = 0; a < MAX_MTEX; a++) { + MTex *mtex = ma->mtex[a]; + if (mtex && mtex->tex && mtex->tex->ima) { + + Image *image = mtex->tex->ima; + std::string name(id_name(image)); + name = translate_id(name); + char rel[FILE_MAX]; + char abs[FILE_MAX]; + char src[FILE_MAX]; + char dir[FILE_MAX]; + + BLI_split_dirfile(mfilename, dir, NULL); + + BKE_rebase_path(abs, sizeof(abs), rel, sizeof(rel), G.sce, image->name, dir); + + if (abs[0] != '\0') { + + // make absolute source path + BLI_strncpy(src, image->name, sizeof(src)); + BLI_path_abs(src, G.sce); + + // make dest directory if it doesn't exist + BLI_make_existing_file(abs); + + if (BLI_copy_fileops(src, abs) != 0) { + fprintf(stderr, "Cannot copy image to file's directory. \n"); + } + } + + if (find(mImages.begin(), mImages.end(), name) == mImages.end()) { + COLLADASW::Image img(COLLADABU::URI(COLLADABU::URI::nativePathToUri(rel)), name); + img.add(mSW); + + mImages.push_back(name); + } + } + } +} diff --git a/source/blender/collada/ImageExporter.h b/source/blender/collada/ImageExporter.h new file mode 100644 index 00000000000..4ee9aba2f6d --- /dev/null +++ b/source/blender/collada/ImageExporter.h @@ -0,0 +1,50 @@ +/** + * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed, + * Nathan Letwory + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __IMAGEEXPORTER_H__ +#define __IMAGEEXPORTER_H__ + +#include +#include + +#include "COLLADASWStreamWriter.h" +#include "COLLADASWLibraryImages.h" + +#include "DNA_material_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +class ImagesExporter: COLLADASW::LibraryImages +{ + const char *mfilename; + std::vector mImages; // contains list of written images, to avoid duplicates +public: + ImagesExporter(COLLADASW::StreamWriter *sw, const char* filename); + + void exportImages(Scene *sce); + void operator()(Material *ma, Object *ob); +}; + +#endif -- cgit v1.2.3 From 2cabb498dcd0664ad8940eefae9d012b175ad829 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 6 Oct 2010 20:29:00 +0000 Subject: bugfix [#23988] The Maya preset as default --- source/blender/windowmanager/intern/wm_operators.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source/blender') diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 5b7d952de77..f0962584801 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1153,7 +1153,6 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *arg_unuse uiStyle *style= U.uistyles.first; struct RecentFile *recent; int i; - Menu menu= {0}; MenuType *mt= WM_menutype_find("USERPREF_MT_splash", TRUE); char url[64]; @@ -1193,9 +1192,13 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *arg_unuse uiBlockSetEmboss(block, UI_EMBOSS); /* show the splash menu (containing interaction presets), using python */ if (mt) { + Menu menu= {0}; menu.layout= layout; menu.type= mt; mt->draw(C, &menu); + +// wmWindowManager *wm= CTX_wm_manager(C); +// uiItemM(layout, C, "USERPREF_MT_keyconfigs", U.keyconfigstr, 0); } uiBlockSetEmboss(block, UI_EMBOSSP); -- cgit v1.2.3 From 15a62013817a6775521a771b42ae15b537450d68 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 6 Oct 2010 20:39:50 +0000 Subject: bugfix [#24168] verts[] was replaced with vertices[] but gives the old info to user. --- source/blender/makesrna/intern/rna_mesh.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender') diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index db5a2062359..dc3cb675f7a 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -955,7 +955,7 @@ static char *rna_VertexGroupElement_path(PointerRNA *ptr) for(a=0, dvert=me->dvert; atotvert; a++, dvert++) for(b=0; btotweight; b++) if(dw == &dvert->dw[b]) - return BLI_sprintfN("verts[%d].groups[%d]", a, b); + return BLI_sprintfN("vertices[%d].groups[%d]", a, b); return NULL; } @@ -972,7 +972,7 @@ static char *rna_MeshEdge_path(PointerRNA *ptr) static char *rna_MeshVertex_path(PointerRNA *ptr) { - return BLI_sprintfN("verts[%d]", (MVert*)ptr->data - ((Mesh*)ptr->id.data)->mvert); + return BLI_sprintfN("vertices[%d]", (MVert*)ptr->data - ((Mesh*)ptr->id.data)->mvert); } static char *rna_MeshTextureFaceLayer_path(PointerRNA *ptr) -- cgit v1.2.3 From 47969866e0d2306d6e639105a0410ea18d8e3a05 Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Wed, 6 Oct 2010 20:40:16 +0000 Subject: SVN maintenance. --- source/blender/collada/ArmatureExporter.cpp | 2 +- source/blender/collada/ArmatureExporter.h | 2 +- source/blender/collada/CameraExporter.cpp | 2 +- source/blender/collada/CameraExporter.h | 2 +- source/blender/collada/GeometryExporter.cpp | 2 +- source/blender/collada/GeometryExporter.h | 2 +- source/blender/collada/ImageExporter.cpp | 2 +- source/blender/collada/ImageExporter.h | 2 +- source/blender/collada/InstanceWriter.cpp | 2 +- source/blender/collada/InstanceWriter.h | 2 +- source/blender/collada/LightExporter.cpp | 2 +- source/blender/collada/LightExporter.h | 2 +- source/blender/collada/MaterialExporter.cpp | 2 +- source/blender/collada/MaterialExporter.h | 2 +- source/blender/collada/TransformWriter.cpp | 2 +- source/blender/collada/TransformWriter.h | 2 +- source/blender/collada/collada_internal.cpp | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) (limited to 'source/blender') diff --git a/source/blender/collada/ArmatureExporter.cpp b/source/blender/collada/ArmatureExporter.cpp index bf75baaf89d..255fb03da10 100644 --- a/source/blender/collada/ArmatureExporter.cpp +++ b/source/blender/collada/ArmatureExporter.cpp @@ -1,5 +1,5 @@ /** - * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/collada/ArmatureExporter.h b/source/blender/collada/ArmatureExporter.h index fc3864a6c0f..8d2508282bd 100644 --- a/source/blender/collada/ArmatureExporter.h +++ b/source/blender/collada/ArmatureExporter.h @@ -1,5 +1,5 @@ /** - * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/collada/CameraExporter.cpp b/source/blender/collada/CameraExporter.cpp index b4ccfd5d6d1..c3a6cda8b3c 100644 --- a/source/blender/collada/CameraExporter.cpp +++ b/source/blender/collada/CameraExporter.cpp @@ -1,5 +1,5 @@ /** - * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/collada/CameraExporter.h b/source/blender/collada/CameraExporter.h index a4605b99f52..fd20c934c96 100644 --- a/source/blender/collada/CameraExporter.h +++ b/source/blender/collada/CameraExporter.h @@ -1,5 +1,5 @@ /** - * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp index b06551a97b6..1aef6e6489a 100644 --- a/source/blender/collada/GeometryExporter.cpp +++ b/source/blender/collada/GeometryExporter.cpp @@ -1,5 +1,5 @@ /** - * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/collada/GeometryExporter.h b/source/blender/collada/GeometryExporter.h index 4ea3cb4efdf..7a78b676f49 100644 --- a/source/blender/collada/GeometryExporter.h +++ b/source/blender/collada/GeometryExporter.h @@ -1,5 +1,5 @@ /** - * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/collada/ImageExporter.cpp b/source/blender/collada/ImageExporter.cpp index 3bcce313aa5..ce40846ba59 100644 --- a/source/blender/collada/ImageExporter.cpp +++ b/source/blender/collada/ImageExporter.cpp @@ -1,5 +1,5 @@ /** - * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/collada/ImageExporter.h b/source/blender/collada/ImageExporter.h index 4ee9aba2f6d..13854d00730 100644 --- a/source/blender/collada/ImageExporter.h +++ b/source/blender/collada/ImageExporter.h @@ -1,5 +1,5 @@ /** - * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/collada/InstanceWriter.cpp b/source/blender/collada/InstanceWriter.cpp index a3260c85f68..746f41fac00 100644 --- a/source/blender/collada/InstanceWriter.cpp +++ b/source/blender/collada/InstanceWriter.cpp @@ -1,5 +1,5 @@ /** - * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/collada/InstanceWriter.h b/source/blender/collada/InstanceWriter.h index f7585bb20db..810bd04c7de 100644 --- a/source/blender/collada/InstanceWriter.h +++ b/source/blender/collada/InstanceWriter.h @@ -1,5 +1,5 @@ /** - * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/collada/LightExporter.cpp b/source/blender/collada/LightExporter.cpp index 0bedce41bc0..7327b309889 100644 --- a/source/blender/collada/LightExporter.cpp +++ b/source/blender/collada/LightExporter.cpp @@ -1,5 +1,5 @@ /** - * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/collada/LightExporter.h b/source/blender/collada/LightExporter.h index 70fa88d6193..3a4a481e471 100644 --- a/source/blender/collada/LightExporter.h +++ b/source/blender/collada/LightExporter.h @@ -1,5 +1,5 @@ /** - * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/collada/MaterialExporter.cpp b/source/blender/collada/MaterialExporter.cpp index 66ebe2d9ed8..d155b2196ff 100644 --- a/source/blender/collada/MaterialExporter.cpp +++ b/source/blender/collada/MaterialExporter.cpp @@ -1,5 +1,5 @@ /** - * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/collada/MaterialExporter.h b/source/blender/collada/MaterialExporter.h index 972cd8bd8e5..2138d26e6a8 100644 --- a/source/blender/collada/MaterialExporter.h +++ b/source/blender/collada/MaterialExporter.h @@ -1,5 +1,5 @@ /** - * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/collada/TransformWriter.cpp b/source/blender/collada/TransformWriter.cpp index 21260a2d4f1..a373191e773 100644 --- a/source/blender/collada/TransformWriter.cpp +++ b/source/blender/collada/TransformWriter.cpp @@ -1,5 +1,5 @@ /** - * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/collada/TransformWriter.h b/source/blender/collada/TransformWriter.h index 29aef721afb..054a28c08a1 100644 --- a/source/blender/collada/TransformWriter.h +++ b/source/blender/collada/TransformWriter.h @@ -1,5 +1,5 @@ /** - * $Id: DocumentExporter.cpp 32309 2010-10-05 00:05:14Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/collada/collada_internal.cpp b/source/blender/collada/collada_internal.cpp index cfa94e60199..67ee4818f7e 100644 --- a/source/blender/collada/collada_internal.cpp +++ b/source/blender/collada/collada_internal.cpp @@ -1,5 +1,5 @@ /** - * $Id: collada_internal.h 32309 2010-10-05 00:05:14Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * -- cgit v1.2.3 From 2ef0d5e13460fb231857697226b85d19a893c9ea Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 6 Oct 2010 21:54:30 +0000 Subject: remove calls to WM_event_add_mousemove r22031, from view2d operators since it would cause a feedback loop where the operator apply function would keep using mousemove events and creating them. This was added for view updates but think it needs to be solved a better way. --- source/blender/editors/interface/view2d_ops.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index de1b26e987b..e10f0f20938 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -146,7 +146,6 @@ static void view_pan_apply(bContext *C, wmOperator *op) ED_region_tag_redraw(vpd->ar); UI_view2d_sync(vpd->sc, vpd->sa, v2d, V2D_LOCK_COPY); - WM_event_add_mousemove(C); /* exceptions */ if (vpd->sa->spacetype==SPACE_OUTLINER) { @@ -628,7 +627,6 @@ static void view_zoomstep_apply(bContext *C, wmOperator *op) /* request updates to be done... */ ED_region_tag_redraw(vzd->ar); UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY); - WM_event_add_mousemove(C); } /* --------------- Individual Operators ------------------- */ @@ -822,7 +820,6 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op) /* request updates to be done... */ ED_region_tag_redraw(vzd->ar); UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY); - WM_event_add_mousemove(C); } /* cleanup temp customdata */ @@ -1095,7 +1092,6 @@ static int view_borderzoom_exec(bContext *C, wmOperator *op) /* request updates to be done... */ ED_region_tag_redraw(ar); UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY); - WM_event_add_mousemove(C); return OPERATOR_FINISHED; } @@ -1355,7 +1351,6 @@ static void scroller_activate_apply(bContext *C, wmOperator *op) /* request updates to be done... */ ED_region_tag_redraw(vsm->ar); UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY); - WM_event_add_mousemove(C); } /* handle user input for scrollers - calculations of mouse-movement need to be done here, not in the apply callback! */ @@ -1560,7 +1555,6 @@ static int reset_exec(bContext *C, wmOperator *op) /* request updates to be done... */ ED_region_tag_redraw(ar); UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY); - WM_event_add_mousemove(C); return OPERATOR_FINISHED; } -- cgit v1.2.3 From 942d5dd804d27b67517e566a0d52dc466b3b247f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 7 Oct 2010 00:14:21 +0000 Subject: bugfix [#24158] Object text fields immediately search based on existing content also remove some unused struct members from uiBlock/uiBut. --- source/blender/editors/include/UI_interface.h | 9 +++++---- source/blender/editors/interface/interface.c | 4 ++-- .../blender/editors/interface/interface_handlers.c | 1 + source/blender/editors/interface/interface_intern.h | 20 ++++++++++---------- source/blender/editors/interface/interface_layout.c | 3 ++- 5 files changed, 20 insertions(+), 17 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 54a627da2da..4689153c9f5 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -77,17 +77,18 @@ typedef struct uiLayout uiLayout; #define UI_EMBOSST 3 /* Table */ /* uiBlock->direction */ +#define UI_DIRECTION (UI_TOP|UI_DOWN|UI_LEFT|UI_RIGHT) #define UI_TOP 1 #define UI_DOWN 2 #define UI_LEFT 4 #define UI_RIGHT 8 -#define UI_DIRECTION 15 + #define UI_CENTER 16 #define UI_SHIFT_FLIPPED 32 /* uiBlock->autofill (not yet used) */ -#define UI_BLOCK_COLLUMNS 1 -#define UI_BLOCK_ROWS 2 +// #define UI_BLOCK_COLLUMNS 1 +// #define UI_BLOCK_ROWS 2 /* uiBlock->flag (controls) */ #define UI_BLOCK_LOOP 1 @@ -316,7 +317,7 @@ void uiDrawBlock(const struct bContext *C, struct uiBlock *block); uiBlock *uiGetBlock(char *name, struct ARegion *ar); -void uiBlockSetEmboss(uiBlock *block, short dt); +void uiBlockSetEmboss(uiBlock *block, char dt); void uiFreeBlock(const struct bContext *C, uiBlock *block); void uiFreeBlocks(const struct bContext *C, struct ListBase *lb); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index b7ec5565d80..f4866237f46 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -937,7 +937,7 @@ void uiComposeLinks(uiBlock *block) void uiBlockSetButLock(uiBlock *block, int val, char *lockstr) { if(val) { - block->lock |= val; + block->lock= val ? 1:0; block->lockstr= lockstr; } } @@ -1947,7 +1947,7 @@ uiBlock *uiGetBlock(char *name, ARegion *ar) return NULL; } -void uiBlockSetEmboss(uiBlock *block, short dt) +void uiBlockSetEmboss(uiBlock *block, char dt) { block->dt= dt; } diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index c789c721aea..6d8c368db3f 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -1816,6 +1816,7 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle /* only update when typing for TAB key */ if(update && data->interactive) ui_apply_button(C, block, but, data, 1); else ui_check_but(but); + but->changed= TRUE; if(data->searchbox) ui_searchbox_update(C, data->searchbox, but, 1); /* 1 = reset */ diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 3873c5c9092..eb28df54b13 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -206,10 +206,11 @@ struct uiBut { char *tip, *lockstr; BIFIconID icon; - short but_align; /* aligning buttons, horiz/vertical */ - short lock; + char lock; + char dt; + short changed; /* could be made into a single flag */ short modifier_key; - short iconadd, dt; + short iconadd; /* IDPOIN data */ uiIDPoinFuncFP idpoin_func; @@ -296,13 +297,14 @@ struct uiBlock { void *drawextra_arg1; void *drawextra_arg2; - int afterval, flag; - - short direction, dt; - short auto_open, in_use; + int flag; + char direction, dt; + short auto_open; double auto_open_last; - int lock; + char active; // to keep blocks while drawing and free them afterwards + char tooltipdisabled; // to avoid tooltip after click + short lock; char *lockstr; float xofs, yofs; // offset to parent button @@ -314,9 +316,7 @@ struct uiBlock { ListBase saferct; // uiSafetyRct list uiPopupBlockHandle *handle; // handle - int tooltipdisabled; // to avoid tooltip after click - int active; // to keep blocks while drawing and free them afterwards int puphash; // popup menu hash for memory int color_profile; // color profile for correcting linear colors for display diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index e268120fa07..4a9d7a0f6f3 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -1109,6 +1109,7 @@ static void rna_search_cb(const struct bContext *C, void *arg_but, char *str, ui int i=0, iconid=0, flag= RNA_property_flag(but->rnaprop); ListBase *items_list= MEM_callocN(sizeof(ListBase), "items_list"); CollItemSearch *cis; + const int skip_filter= !but->changed; /* build a temporary list of relevant items first */ RNA_PROP_BEGIN(&but->rnasearchpoin, itemptr, but->rnasearchprop) { @@ -1140,7 +1141,7 @@ static void rna_search_cb(const struct bContext *C, void *arg_but, char *str, ui } if(name) { - if(BLI_strcasestr(name, str)) { + if(skip_filter || BLI_strcasestr(name, str)) { cis = MEM_callocN(sizeof(CollItemSearch), "CollectionItemSearch"); cis->name = MEM_dupallocN(name); cis->index = i; -- cgit v1.2.3 From c139faf171e81b81ac0bf29fd27089ac75f8ce89 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Thu, 7 Oct 2010 00:24:42 +0000 Subject: COLLADA: Split EffectsExporter into separate files. --- source/blender/collada/DocumentExporter.cpp | 272 +------------------------ source/blender/collada/EffectExporter.cpp | 306 ++++++++++++++++++++++++++++ source/blender/collada/EffectExporter.h | 62 ++++++ 3 files changed, 369 insertions(+), 271 deletions(-) create mode 100644 source/blender/collada/EffectExporter.cpp create mode 100644 source/blender/collada/EffectExporter.h (limited to 'source/blender') diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp index 9bf84c7e606..cbcb3984018 100644 --- a/source/blender/collada/DocumentExporter.cpp +++ b/source/blender/collada/DocumentExporter.cpp @@ -108,6 +108,7 @@ extern char build_rev[]; #include "ArmatureExporter.h" #include "CameraExporter.h" +#include "EffectExporter.h" #include "GeometryExporter.h" #include "ImageExporter.h" #include "LightExporter.h" @@ -155,18 +156,6 @@ void forEachObjectInScene(Scene *sce, Functor &f) -// OB_MESH is assumed -std::string getActiveUVLayerName(Object *ob) -{ - Mesh *me = (Mesh*)ob->data; - - int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE); - if (num_layers) - return std::string(bc_CustomData_get_active_layer_name(&me->fdata, CD_MTFACE)); - - return ""; -} - class SceneExporter: COLLADASW::LibraryVisualScenes, protected TransformWriter, protected InstanceWriter { ArmatureExporter *arm_exporter; @@ -299,265 +288,6 @@ public: } }; -class EffectsExporter: COLLADASW::LibraryEffects -{ -public: - EffectsExporter(COLLADASW::StreamWriter *sw) : COLLADASW::LibraryEffects(sw){} - void exportEffects(Scene *sce) - { - openLibrary(); - MaterialFunctor mf; - mf.forEachMaterialInScene(sce, *this); - - closeLibrary(); - } - - void operator()(Material *ma, Object *ob) - { - // create a list of indices to textures of type TEX_IMAGE - std::vector tex_indices; - createTextureIndices(ma, tex_indices); - - openEffect(translate_id(id_name(ma)) + "-effect"); - - COLLADASW::EffectProfile ep(mSW); - ep.setProfileType(COLLADASW::EffectProfile::COMMON); - ep.openProfile(); - // set shader type - one of three blinn, phong or lambert - if (ma->spec_shader == MA_SPEC_BLINN) { - ep.setShaderType(COLLADASW::EffectProfile::BLINN); - // shininess - ep.setShininess(ma->har); - } - else if (ma->spec_shader == MA_SPEC_PHONG) { - ep.setShaderType(COLLADASW::EffectProfile::PHONG); - // shininess - ep.setShininess(ma->har); - } - else { - // XXX write warning "Current shader type is not supported" - ep.setShaderType(COLLADASW::EffectProfile::LAMBERT); - } - // index of refraction - if (ma->mode & MA_RAYTRANSP) { - ep.setIndexOfRefraction(ma->ang); - } - else { - ep.setIndexOfRefraction(1.0f); - } - - COLLADASW::ColorOrTexture cot; - - // transparency - if (ma->mode & MA_TRANSP) { - // Tod: because we are in A_ONE mode transparency is calculated like this: - ep.setTransparency(ma->alpha); - // cot = getcol(1.0f, 1.0f, 1.0f, 1.0f); - // ep.setTransparent(cot); - } - - // emission - cot=getcol(ma->emit, ma->emit, ma->emit, 1.0f); - ep.setEmission(cot); - - // diffuse multiplied by diffuse intensity - cot = getcol(ma->r * ma->ref, ma->g * ma->ref, ma->b * ma->ref, 1.0f); - ep.setDiffuse(cot); - - // ambient - cot = getcol(ma->ambr, ma->ambg, ma->ambb, 1.0f); - ep.setAmbient(cot); - - // reflective, reflectivity - if (ma->mode & MA_RAYMIRROR) { - cot = getcol(ma->mirr, ma->mirg, ma->mirb, 1.0f); - ep.setReflective(cot); - ep.setReflectivity(ma->ray_mirror); - } - // else { - // cot = getcol(ma->specr, ma->specg, ma->specb, 1.0f); - // ep.setReflective(cot); - // ep.setReflectivity(ma->spec); - // } - - // specular - if (ep.getShaderType() != COLLADASW::EffectProfile::LAMBERT) { - cot = getcol(ma->specr * ma->spec, ma->specg * ma->spec, ma->specb * ma->spec, 1.0f); - ep.setSpecular(cot); - } - - // XXX make this more readable if possible - - // create and for each image - COLLADASW::Sampler samplers[MAX_MTEX]; - //COLLADASW::Surface surfaces[MAX_MTEX]; - //void *samp_surf[MAX_MTEX][2]; - void *samp_surf[MAX_MTEX][1]; - - // image to index to samp_surf map - // samp_surf[index] stores 2 pointers, sampler and surface - std::map im_samp_map; - - unsigned int a, b; - for (a = 0, b = 0; a < tex_indices.size(); a++) { - MTex *t = ma->mtex[tex_indices[a]]; - Image *ima = t->tex->ima; - - // Image not set for texture - if(!ima) continue; - - std::string key(id_name(ima)); - key = translate_id(key); - - // create only one / pair for each unique image - if (im_samp_map.find(key) == im_samp_map.end()) { - // // - // COLLADASW::Surface surface(COLLADASW::Surface::SURFACE_TYPE_2D, - // key + COLLADASW::Surface::SURFACE_SID_SUFFIX); - // COLLADASW::SurfaceInitOption sio(COLLADASW::SurfaceInitOption::INIT_FROM); - // sio.setImageReference(key); - // surface.setInitOption(sio); - - // COLLADASW::NewParamSurface surface(mSW); - // surface->setParamType(COLLADASW::CSW_SURFACE_TYPE_2D); - - // - COLLADASW::Sampler sampler(COLLADASW::Sampler::SAMPLER_TYPE_2D, - key + COLLADASW::Sampler::SAMPLER_SID_SUFFIX, - key + COLLADASW::Sampler::SURFACE_SID_SUFFIX); - sampler.setImageId(key); - // copy values to arrays since they will live longer - samplers[a] = sampler; - //surfaces[a] = surface; - - // store pointers so they can be used later when we create s - samp_surf[b][0] = &samplers[a]; - //samp_surf[b][1] = &surfaces[a]; - - im_samp_map[key] = b; - b++; - } - } - - // used as fallback when MTex->uvname is "" (this is pretty common) - // it is indeed the correct value to use in that case - std::string active_uv(getActiveUVLayerName(ob)); - - // write textures - // XXX very slow - for (a = 0; a < tex_indices.size(); a++) { - MTex *t = ma->mtex[tex_indices[a]]; - Image *ima = t->tex->ima; - - // Image not set for texture - if(!ima) continue; - - // we assume map input is always TEXCO_UV - - std::string key(id_name(ima)); - key = translate_id(key); - int i = im_samp_map[key]; - COLLADASW::Sampler *sampler = (COLLADASW::Sampler*)samp_surf[i][0]; - //COLLADASW::Surface *surface = (COLLADASW::Surface*)samp_surf[i][1]; - - std::string uvname = strlen(t->uvname) ? t->uvname : active_uv; - - // color - if (t->mapto & MAP_COL) { - ep.setDiffuse(createTexture(ima, uvname, sampler)); - } - // ambient - if (t->mapto & MAP_AMB) { - ep.setAmbient(createTexture(ima, uvname, sampler)); - } - // specular - if (t->mapto & MAP_SPEC) { - ep.setSpecular(createTexture(ima, uvname, sampler)); - } - // emission - if (t->mapto & MAP_EMIT) { - ep.setEmission(createTexture(ima, uvname, sampler)); - } - // reflective - if (t->mapto & MAP_REF) { - ep.setReflective(createTexture(ima, uvname, sampler)); - } - // alpha - if (t->mapto & MAP_ALPHA) { - ep.setTransparent(createTexture(ima, uvname, sampler)); - } - // extension: - // Normal map --> Must be stored with tag as different technique, - // since COLLADA doesn't support normal maps, even in current COLLADA 1.5. - if (t->mapto & MAP_NORM) { - COLLADASW::Texture texture(key); - texture.setTexcoord(uvname); - texture.setSampler(*sampler); - // technique FCOLLADA, with the tag, is most likely the best understood, - // most widespread de-facto standard. - texture.setProfileName("FCOLLADA"); - texture.setChildElementName("bump"); - ep.addExtraTechniqueColorOrTexture(COLLADASW::ColorOrTexture(texture)); - } - } - // performs the actual writing - ep.addProfileElements(); - bool twoSided = false; - if (ob->type == OB_MESH && ob->data) { - Mesh *me = (Mesh*)ob->data; - if (me->flag & ME_TWOSIDED) - twoSided = true; - } - if (twoSided) - ep.addExtraTechniqueParameter("GOOGLEEARTH", "show_double_sided", 1); - ep.addExtraTechniques(mSW); - - ep.closeProfile(); - if (twoSided) - mSW->appendTextBlock("1"); - closeEffect(); - } - - COLLADASW::ColorOrTexture createTexture(Image *ima, - std::string& uv_layer_name, - COLLADASW::Sampler *sampler - /*COLLADASW::Surface *surface*/) - { - - COLLADASW::Texture texture(translate_id(id_name(ima))); - texture.setTexcoord(uv_layer_name); - //texture.setSurface(*surface); - texture.setSampler(*sampler); - - COLLADASW::ColorOrTexture cot(texture); - return cot; - } - - COLLADASW::ColorOrTexture getcol(float r, float g, float b, float a) - { - COLLADASW::Color color(r,g,b,a); - COLLADASW::ColorOrTexture cot(color); - return cot; - } - - //returns the array of mtex indices which have image - //need this for exporting textures - void createTextureIndices(Material *ma, std::vector &indices) - { - indices.clear(); - - for (int a = 0; a < MAX_MTEX; a++) { - if (ma->mtex[a] && - ma->mtex[a]->tex && - ma->mtex[a]->tex->type == TEX_IMAGE && - ma->mtex[a]->texco == TEXCO_UV){ - indices.push_back(a); - } - } - } -}; - - // TODO: it would be better to instantiate animations rather than create a new one per object // COLLADA allows this through multiple s in . // For this to work, we need to know objects that use a certain action. diff --git a/source/blender/collada/EffectExporter.cpp b/source/blender/collada/EffectExporter.cpp new file mode 100644 index 00000000000..af6fa09a25b --- /dev/null +++ b/source/blender/collada/EffectExporter.cpp @@ -0,0 +1,306 @@ +/** + * $Id: LightExporter.h 32355 2010-10-06 20:40:16Z gsrb3d $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed, + * Nathan Letwory + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include + +#include "COLLADASWEffectProfile.h" + +#include "EffectExporter.h" +#include "MaterialExporter.h" + +#include "DNA_mesh_types.h" +#include "DNA_texture_types.h" + +#include "BKE_customdata.h" + +#include "collada_internal.h" +#include "collada_utils.h" + +// OB_MESH is assumed +static std::string getActiveUVLayerName(Object *ob) +{ + Mesh *me = (Mesh*)ob->data; + + int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE); + if (num_layers) + return std::string(bc_CustomData_get_active_layer_name(&me->fdata, CD_MTFACE)); + + return ""; +} + + +EffectsExporter::EffectsExporter(COLLADASW::StreamWriter *sw) : COLLADASW::LibraryEffects(sw){} +void EffectsExporter::exportEffects(Scene *sce) +{ + openLibrary(); + MaterialFunctor mf; + mf.forEachMaterialInScene(sce, *this); + + closeLibrary(); +} + +void EffectsExporter::operator()(Material *ma, Object *ob) +{ + // create a list of indices to textures of type TEX_IMAGE + std::vector tex_indices; + createTextureIndices(ma, tex_indices); + + openEffect(translate_id(id_name(ma)) + "-effect"); + + COLLADASW::EffectProfile ep(mSW); + ep.setProfileType(COLLADASW::EffectProfile::COMMON); + ep.openProfile(); + // set shader type - one of three blinn, phong or lambert + if (ma->spec_shader == MA_SPEC_BLINN) { + ep.setShaderType(COLLADASW::EffectProfile::BLINN); + // shininess + ep.setShininess(ma->har); + } + else if (ma->spec_shader == MA_SPEC_PHONG) { + ep.setShaderType(COLLADASW::EffectProfile::PHONG); + // shininess + ep.setShininess(ma->har); + } + else { + // XXX write warning "Current shader type is not supported" + ep.setShaderType(COLLADASW::EffectProfile::LAMBERT); + } + // index of refraction + if (ma->mode & MA_RAYTRANSP) { + ep.setIndexOfRefraction(ma->ang); + } + else { + ep.setIndexOfRefraction(1.0f); + } + + COLLADASW::ColorOrTexture cot; + + // transparency + if (ma->mode & MA_TRANSP) { + // Tod: because we are in A_ONE mode transparency is calculated like this: + ep.setTransparency(ma->alpha); + // cot = getcol(1.0f, 1.0f, 1.0f, 1.0f); + // ep.setTransparent(cot); + } + + // emission + cot=getcol(ma->emit, ma->emit, ma->emit, 1.0f); + ep.setEmission(cot); + + // diffuse multiplied by diffuse intensity + cot = getcol(ma->r * ma->ref, ma->g * ma->ref, ma->b * ma->ref, 1.0f); + ep.setDiffuse(cot); + + // ambient + cot = getcol(ma->ambr, ma->ambg, ma->ambb, 1.0f); + ep.setAmbient(cot); + + // reflective, reflectivity + if (ma->mode & MA_RAYMIRROR) { + cot = getcol(ma->mirr, ma->mirg, ma->mirb, 1.0f); + ep.setReflective(cot); + ep.setReflectivity(ma->ray_mirror); + } + // else { + // cot = getcol(ma->specr, ma->specg, ma->specb, 1.0f); + // ep.setReflective(cot); + // ep.setReflectivity(ma->spec); + // } + + // specular + if (ep.getShaderType() != COLLADASW::EffectProfile::LAMBERT) { + cot = getcol(ma->specr * ma->spec, ma->specg * ma->spec, ma->specb * ma->spec, 1.0f); + ep.setSpecular(cot); + } + + // XXX make this more readable if possible + + // create and for each image + COLLADASW::Sampler samplers[MAX_MTEX]; + //COLLADASW::Surface surfaces[MAX_MTEX]; + //void *samp_surf[MAX_MTEX][2]; + void *samp_surf[MAX_MTEX][1]; + + // image to index to samp_surf map + // samp_surf[index] stores 2 pointers, sampler and surface + std::map im_samp_map; + + unsigned int a, b; + for (a = 0, b = 0; a < tex_indices.size(); a++) { + MTex *t = ma->mtex[tex_indices[a]]; + Image *ima = t->tex->ima; + + // Image not set for texture + if(!ima) continue; + + std::string key(id_name(ima)); + key = translate_id(key); + + // create only one / pair for each unique image + if (im_samp_map.find(key) == im_samp_map.end()) { + // // + // COLLADASW::Surface surface(COLLADASW::Surface::SURFACE_TYPE_2D, + // key + COLLADASW::Surface::SURFACE_SID_SUFFIX); + // COLLADASW::SurfaceInitOption sio(COLLADASW::SurfaceInitOption::INIT_FROM); + // sio.setImageReference(key); + // surface.setInitOption(sio); + + // COLLADASW::NewParamSurface surface(mSW); + // surface->setParamType(COLLADASW::CSW_SURFACE_TYPE_2D); + + // + COLLADASW::Sampler sampler(COLLADASW::Sampler::SAMPLER_TYPE_2D, + key + COLLADASW::Sampler::SAMPLER_SID_SUFFIX, + key + COLLADASW::Sampler::SURFACE_SID_SUFFIX); + sampler.setImageId(key); + // copy values to arrays since they will live longer + samplers[a] = sampler; + //surfaces[a] = surface; + + // store pointers so they can be used later when we create s + samp_surf[b][0] = &samplers[a]; + //samp_surf[b][1] = &surfaces[a]; + + im_samp_map[key] = b; + b++; + } + } + + // used as fallback when MTex->uvname is "" (this is pretty common) + // it is indeed the correct value to use in that case + std::string active_uv(getActiveUVLayerName(ob)); + + // write textures + // XXX very slow + for (a = 0; a < tex_indices.size(); a++) { + MTex *t = ma->mtex[tex_indices[a]]; + Image *ima = t->tex->ima; + + // Image not set for texture + if(!ima) continue; + + // we assume map input is always TEXCO_UV + + std::string key(id_name(ima)); + key = translate_id(key); + int i = im_samp_map[key]; + COLLADASW::Sampler *sampler = (COLLADASW::Sampler*)samp_surf[i][0]; + //COLLADASW::Surface *surface = (COLLADASW::Surface*)samp_surf[i][1]; + + std::string uvname = strlen(t->uvname) ? t->uvname : active_uv; + + // color + if (t->mapto & MAP_COL) { + ep.setDiffuse(createTexture(ima, uvname, sampler)); + } + // ambient + if (t->mapto & MAP_AMB) { + ep.setAmbient(createTexture(ima, uvname, sampler)); + } + // specular + if (t->mapto & MAP_SPEC) { + ep.setSpecular(createTexture(ima, uvname, sampler)); + } + // emission + if (t->mapto & MAP_EMIT) { + ep.setEmission(createTexture(ima, uvname, sampler)); + } + // reflective + if (t->mapto & MAP_REF) { + ep.setReflective(createTexture(ima, uvname, sampler)); + } + // alpha + if (t->mapto & MAP_ALPHA) { + ep.setTransparent(createTexture(ima, uvname, sampler)); + } + // extension: + // Normal map --> Must be stored with tag as different technique, + // since COLLADA doesn't support normal maps, even in current COLLADA 1.5. + if (t->mapto & MAP_NORM) { + COLLADASW::Texture texture(key); + texture.setTexcoord(uvname); + texture.setSampler(*sampler); + // technique FCOLLADA, with the tag, is most likely the best understood, + // most widespread de-facto standard. + texture.setProfileName("FCOLLADA"); + texture.setChildElementName("bump"); + ep.addExtraTechniqueColorOrTexture(COLLADASW::ColorOrTexture(texture)); + } + } + // performs the actual writing + ep.addProfileElements(); + bool twoSided = false; + if (ob->type == OB_MESH && ob->data) { + Mesh *me = (Mesh*)ob->data; + if (me->flag & ME_TWOSIDED) + twoSided = true; + } + if (twoSided) + ep.addExtraTechniqueParameter("GOOGLEEARTH", "show_double_sided", 1); + ep.addExtraTechniques(mSW); + + ep.closeProfile(); + if (twoSided) + mSW->appendTextBlock("1"); + closeEffect(); +} + +COLLADASW::ColorOrTexture EffectsExporter::createTexture(Image *ima, + std::string& uv_layer_name, + COLLADASW::Sampler *sampler + /*COLLADASW::Surface *surface*/) +{ + + COLLADASW::Texture texture(translate_id(id_name(ima))); + texture.setTexcoord(uv_layer_name); + //texture.setSurface(*surface); + texture.setSampler(*sampler); + + COLLADASW::ColorOrTexture cot(texture); + return cot; +} + +COLLADASW::ColorOrTexture EffectsExporter::getcol(float r, float g, float b, float a) +{ + COLLADASW::Color color(r,g,b,a); + COLLADASW::ColorOrTexture cot(color); + return cot; +} + +//returns the array of mtex indices which have image +//need this for exporting textures +void EffectsExporter::createTextureIndices(Material *ma, std::vector &indices) +{ + indices.clear(); + + for (int a = 0; a < MAX_MTEX; a++) { + if (ma->mtex[a] && + ma->mtex[a]->tex && + ma->mtex[a]->tex->type == TEX_IMAGE && + ma->mtex[a]->texco == TEXCO_UV){ + indices.push_back(a); + } + } +} diff --git a/source/blender/collada/EffectExporter.h b/source/blender/collada/EffectExporter.h new file mode 100644 index 00000000000..ecd5d9a3c16 --- /dev/null +++ b/source/blender/collada/EffectExporter.h @@ -0,0 +1,62 @@ +/** + * $Id: LightExporter.h 32355 2010-10-06 20:40:16Z gsrb3d $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed, + * Nathan Letwory + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __EFFECTEXPORTER_H__ +#define __EFFECTEXPORTER_H__ + +#include +#include + +#include "COLLADASWColorOrTexture.h" +#include "COLLADASWStreamWriter.h" +#include "COLLADASWSampler.h" +#include "COLLADASWLibraryEffects.h" + +#include "DNA_image_types.h" +#include "DNA_material_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +class EffectsExporter: COLLADASW::LibraryEffects +{ +public: + EffectsExporter(COLLADASW::StreamWriter *sw); + void exportEffects(Scene *sce); + + void operator()(Material *ma, Object *ob); + + COLLADASW::ColorOrTexture createTexture(Image *ima, + std::string& uv_layer_name, + COLLADASW::Sampler *sampler + /*COLLADASW::Surface *surface*/); + + COLLADASW::ColorOrTexture getcol(float r, float g, float b, float a); + + //returns the array of mtex indices which have image + //need this for exporting textures + void createTextureIndices(Material *ma, std::vector &indices); +}; + +#endif -- cgit v1.2.3 From c9453b1357dcb878dff6efc9dd3597452d6dc762 Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Thu, 7 Oct 2010 01:20:59 +0000 Subject: SVN maintenance. --- source/blender/collada/EffectExporter.cpp | 2 +- source/blender/collada/EffectExporter.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender') diff --git a/source/blender/collada/EffectExporter.cpp b/source/blender/collada/EffectExporter.cpp index af6fa09a25b..45b6450e444 100644 --- a/source/blender/collada/EffectExporter.cpp +++ b/source/blender/collada/EffectExporter.cpp @@ -1,5 +1,5 @@ /** - * $Id: LightExporter.h 32355 2010-10-06 20:40:16Z gsrb3d $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/collada/EffectExporter.h b/source/blender/collada/EffectExporter.h index ecd5d9a3c16..e8f8754b20a 100644 --- a/source/blender/collada/EffectExporter.h +++ b/source/blender/collada/EffectExporter.h @@ -1,5 +1,5 @@ /** - * $Id: LightExporter.h 32355 2010-10-06 20:40:16Z gsrb3d $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * -- cgit v1.2.3 From 8a4fe62843f8aa311226f543d14bd3e5440ffe7d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 7 Oct 2010 10:04:07 +0000 Subject: misc fixes found with clang's static checker. --- source/blender/blenkernel/intern/anim.c | 2 +- source/blender/blenkernel/intern/library.c | 9 ++++---- source/blender/blenkernel/intern/modifier.c | 4 ++-- source/blender/blenkernel/intern/pointcache.c | 2 +- source/blender/blenlib/intern/math_color.c | 5 +++++ source/blender/editors/curve/editcurve.c | 8 ++++---- source/blender/editors/interface/interface_icons.c | 24 +++++++++++++++------- .../blender/editors/interface/interface_regions.c | 2 +- source/blender/editors/space_logic/logic_window.c | 6 +++--- .../editors/space_sequencer/sequencer_edit.c | 2 +- source/blender/editors/space_view3d/drawmesh.c | 13 ++++++------ source/blender/editors/space_view3d/drawobject.c | 4 +++- source/blender/editors/space_view3d/view3d_edit.c | 5 +---- source/blender/editors/transform/transform_snap.c | 4 ++++ source/blender/gpu/intern/gpu_material.c | 2 +- source/blender/imbuf/intern/thumbs_blend.c | 2 +- .../blender/render/intern/source/convertblender.c | 6 +++--- 17 files changed, 59 insertions(+), 41 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 6da9f2bbabc..b2feb01352e 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -648,7 +648,7 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir, float *quat, totfac= data[1]+data[2]; if(totfac>FLT_EPSILON) interp_qt_qtqt(q2, p1->quat, p2->quat, data[2] / totfac); - else QUATCOPY(q1, p3->quat); + else QUATCOPY(q2, p3->quat); totfac = data[0]+data[1]+data[2]+data[3]; if(totfac>FLT_EPSILON) interp_qt_qtqt(quat, q1, q2, (data[1]+data[2]) / totfac); diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 834e7de5811..93e4b5fcfbe 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "MEM_guardedalloc.h" @@ -649,11 +650,9 @@ void *copy_libblock(void *rt) lb= which_libbase(G.main, GS(id->name)); idn= alloc_libblock(lb, GS(id->name), id->name+2); - - if(idn==NULL) { - printf("ERROR: Illegal ID name for %s (Crashing now)\n", id->name); - } - + + assert(idn != NULL); + idn_len= MEM_allocN_len(idn); if(idn_len - sizeof(ID) > 0) { cp= (char *)id; diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 43d26f26d1f..d7c95a007e5 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -63,8 +63,8 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) types_init= 0; } - if(type >= 0 && type < NUM_MODIFIER_TYPES && - types[type]->name[0] != '\0') { + /* type unsigned, no need to chech < 0 */ + if(type < NUM_MODIFIER_TYPES && types[type]->name[0] != '\0') { return types[type]; } else { diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 4ec12b3482c..a15e66ed843 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -1082,7 +1082,7 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int dup static int ptcache_path(PTCacheID *pid, char *filename) { - Library *lib= (pid)? pid->ob->id.lib: NULL; + Library *lib= (pid->ob)? pid->ob->id.lib: NULL; const char *blendfilename= (lib && (pid->cache->flag & PTCACHE_IGNORE_LIBPATH)==0) ? lib->filepath: G.sce; size_t i; diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c index 2b6a091cc8d..f0ef8b2c93d 100644 --- a/source/blender/blenlib/intern/math_color.c +++ b/source/blender/blenlib/intern/math_color.c @@ -25,6 +25,7 @@ * ***** END GPL LICENSE BLOCK ***** * */ +#include #include "BLI_math.h" @@ -133,6 +134,8 @@ void rgb_to_ycc(float r, float g, float b, float *ly, float *lcb, float *lcr, in cb=(-0.16874f*sr)-(0.33126f*sg)+(0.5f*sb)+128.0f; cr=(0.5f*sr)-(0.41869f*sg)-(0.08131f*sb)+128.0f; break; + default: + assert(!"invalid colorspace"); } *ly=y; @@ -163,6 +166,8 @@ void ycc_to_rgb(float y, float cb, float cr, float *lr, float *lg, float *lb, in g=y-0.34414f*cb - 0.71414f*cr + 135.45984f; b=y+1.772f*cb - 226.816f; break; + default: + assert(!"invalid colorspace"); } *lr=r/255.0f; *lg=g/255.0f; diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 6193b6eb916..4c869d25869 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -732,7 +732,7 @@ static void calc_shapeKeys(Object *obedit) int totvert= count_curveverts(&editnurb->nurbs); float (*ofs)[3] = NULL; - float *oldkey, *newkey, *fp, *ofp; + float *oldkey, *newkey, *ofp; /* editing the base key should update others */ if(cu->key->type==KEY_RELATIVE) { @@ -776,7 +776,7 @@ static void calc_shapeKeys(Object *obedit) for (j= 0; j < 3; ++j) { VECSUB(ofs[i], bezt->vec[j], oldbezt->vec[j]); i++; - fp+= 3; + // fp+= 3; // unused } ofs[i++][0]= bezt->alfa - oldbezt->alfa; } else { @@ -796,7 +796,7 @@ static void calc_shapeKeys(Object *obedit) } i += 2; ++bp; - fp += 4; + // fp += 4; //unused } } @@ -809,7 +809,7 @@ static void calc_shapeKeys(Object *obedit) while(currkey) { int apply_offset = (ofs && (currkey != actkey) && (editnurb->shapenr-1 == currkey->relative)); - fp= newkey= MEM_callocN(cu->key->elemsize * totvert, "currkey->data"); + float *fp= newkey= MEM_callocN(cu->key->elemsize * totvert, "currkey->data"); ofp= oldkey = currkey->data; nu= editnurb->nurbs.first; diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 482eece42f6..3fa53b73015 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -622,20 +622,30 @@ static void init_iconfile_list(struct ListBase *list) char *filename = dir[i].relname; if(BLI_testextensie(filename, ".png")) { - + /* check to see if the image is the right size, continue if not */ /* copying strings here should go ok, assuming that we never get back a complete path to file longer than 256 chars */ sprintf(iconfilestr, "%s/%s", icondirstr, filename); - if(BLI_exists(iconfilestr)) bbuf = IMB_loadiffname(iconfilestr, IB_rect); - - ifilex = bbuf->x; - ifiley = bbuf->y; - IMB_freeImBuf(bbuf); + if(BLI_exists(iconfilestr)) + bbuf= IMB_loadiffname(iconfilestr, IB_rect); + else + bbuf= NULL; + + + if(bbuf) { + ifilex = bbuf->x; + ifiley = bbuf->y; + IMB_freeImBuf(bbuf); + } + else { + ifilex= ifiley= 0; + } + /* bad size or failed to load */ if ((ifilex != ICON_IMAGE_W) || (ifiley != ICON_IMAGE_H)) continue; - + /* found a potential icon file, so make an entry for it in the cache list */ ifile = MEM_callocN(sizeof(IconFile), "IconFile"); diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index ff079a4b9e0..53981f202ed 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -1008,7 +1008,7 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but) x2= winx; } } - if(y1 < 0) { + if(y1 < 0) { /* XXX butregion NULL check?, there is one above */ int newy1; UI_view2d_to_region_no_clip(&butregion->v2d, 0, but->y2 + ofsy, 0, &newy1); newy1 += butregion->winrct.ymin; diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c index 4b778e80b0e..148bcf1459f 100644 --- a/source/blender/editors/space_logic/logic_window.c +++ b/source/blender/editors/space_logic/logic_window.c @@ -3712,7 +3712,7 @@ static void draw_actuator_armature(uiLayout *layout, PointerRNA *ptr) break; case ACT_ARM_ENABLE: case ACT_ARM_DISABLE: - if (&pose_ptr.data) { + if (ob->pose) { uiItemPointerR(layout, ptr, "bone", &pose_ptr, "bones", NULL, ICON_BONE_DATA); if (RNA_property_collection_lookup_string(&pose_ptr, bones_prop, aa->posechannel, &pchan_ptr)) @@ -3720,7 +3720,7 @@ static void draw_actuator_armature(uiLayout *layout, PointerRNA *ptr) } break; case ACT_ARM_SETTARGET: - if (&pose_ptr.data) { + if (ob->pose) { uiItemPointerR(layout, ptr, "bone", &pose_ptr, "bones", NULL, ICON_BONE_DATA); if (RNA_property_collection_lookup_string(&pose_ptr, bones_prop, aa->posechannel, &pchan_ptr)) @@ -3731,7 +3731,7 @@ static void draw_actuator_armature(uiLayout *layout, PointerRNA *ptr) uiItemR(layout, ptr, "secondary_target", 0, NULL, 0); break; case ACT_ARM_SETWEIGHT: - if (&pose_ptr.data) { + if (ob->pose) { uiItemPointerR(layout, ptr, "bone", &pose_ptr, "bones", NULL, ICON_BONE_DATA); if (RNA_property_collection_lookup_string(&pose_ptr, bones_prop, aa->posechannel, &pchan_ptr)) diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 84ced036f75..d96b8a27c99 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -159,7 +159,7 @@ static void change_plugin_seq(Scene *scene, char *str) /* called from fileselect struct SeqEffectHandle sh; Sequence *last_seq= seq_active_get(scene); - if(last_seq && last_seq->type != SEQ_PLUGIN) return; + if(last_seq==NULL || last_seq->type != SEQ_PLUGIN) return; sh = get_sequence_effect(last_seq); sh.free(last_seq); diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index 7a7462433d7..cf511a8ad9b 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -536,12 +536,13 @@ static int draw_em_tf_mapped__set_draw(void *userData, int index) static int wpaint__setSolidDrawOptions(void *userData, int index, int *drawSmooth_r) { Mesh *me = (Mesh*)userData; - MTFace *tface = (me->mtface)? &me->mtface[index]: NULL; - MFace *mface = (me->mface)? &me->mface[index]: NULL; - - if ((mface->flag&ME_HIDE) || (tface && (tface->mode&TF_INVISIBLE))) - return 0; - + + if ( (me->mface && me->mface[index].flag & ME_HIDE) || + (me->mtface && (me->mtface[index].mode & TF_INVISIBLE)) + ) { + return 0; + } + *drawSmooth_r = 1; return 1; } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index aba3d04d960..d28813f7522 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -917,6 +917,9 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, copy_m4_m4(imat, rv3d->viewinv); normalize_v3(imat[0]); normalize_v3(imat[1]); + + /* lamp center */ + copy_v3_v3(vec, ob->obmat[3]); /* for AA effects */ glGetFloatv(GL_CURRENT_COLOR, curcol); @@ -931,7 +934,6 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, } /* Inner Circle */ - copy_v3_v3(vec, ob->obmat[3]); glEnable(GL_BLEND); drawcircball(GL_LINE_LOOP, vec, lampsize, imat); glDisable(GL_BLEND); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 4cac0e297d1..9f1b55ee2ce 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -2121,14 +2121,11 @@ static int viewpan_exec(bContext *C, wmOperator *op) pandir = RNA_enum_get(op->ptr, "type"); initgrabz(rv3d, 0.0, 0.0, 0.0); - if(pandir == V3D_VIEW_PANRIGHT) window_to_3d_delta(ar, vec, -32, 0); else if(pandir == V3D_VIEW_PANLEFT) window_to_3d_delta(ar, vec, 32, 0); else if(pandir == V3D_VIEW_PANUP) window_to_3d_delta(ar, vec, 0, -25); else if(pandir == V3D_VIEW_PANDOWN) window_to_3d_delta(ar, vec, 0, 25); - rv3d->ofs[0]+= vec[0]; - rv3d->ofs[1]+= vec[1]; - rv3d->ofs[2]+= vec[2]; + add_v3_v3(rv3d->ofs, vec); if(rv3d->viewlock & RV3D_BOXVIEW) view3d_boxview_sync(CTX_wm_area(C), ar); diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 93331dd0ee3..5b7bcac65f2 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -784,6 +784,10 @@ void CalcSnapGeometry(TransInfo *t, float *vec) if (dist != FLT_MAX) { VECCOPY(loc, p); + /* XXX, is there a correct normal in this case ???, for now just z up */ + no[0]= 0.0; + no[1]= 0.0; + no[2]= 1.0; found = 1; } diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 5f8015be52f..a31ec950711 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -605,7 +605,7 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la Material *ma= shi->mat; GPUMaterial *mat= shi->gpumat; GPUNodeLink *lv, *dist, *visifac, *is, *inp, *i, *vn, *view; - GPUNodeLink *outcol, *specfac, *t, *shadfac; + GPUNodeLink *outcol, *specfac, *t, *shadfac= NULL; float one = 1.0f; if((lamp->mode & LA_ONLYSHADOW) && !(ma->mode & MA_SHADOW)) diff --git a/source/blender/imbuf/intern/thumbs_blend.c b/source/blender/imbuf/intern/thumbs_blend.c index 2fef230f1c2..f1f8383b85e 100644 --- a/source/blender/imbuf/intern/thumbs_blend.c +++ b/source/blender/imbuf/intern/thumbs_blend.c @@ -161,11 +161,11 @@ void IMB_overlayblend_thumb(unsigned int *thumb, int width, int height, float as { int x, y; - int hline, vline; int stride_x= (margin_r - margin_l) - 2; for(y=0; y < height; y++) { for(x=0; x < width; x++, px+=4) { + int hline= 0, vline= 0; if((x > margin_l && x < margin_r) && (y > margin_b && y < margin_t)) { /* interior. skip */ x += stride_x; diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 01dafd2ce4a..e741c622380 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -2341,7 +2341,7 @@ static void init_render_mball(Render *re, ObjectRen *obr) VertRen *ver; VlakRen *vlr, *vlr1; Material *ma; - float *data, *nors, *orco, mat[4][4], imat[3][3], xn, yn, zn; + float *data, *nors, *orco=NULL, mat[4][4], imat[3][3], xn, yn, zn; int a, need_orco, vlakindex, *index; ListBase dispbase= {NULL, NULL}; @@ -2375,7 +2375,7 @@ static void init_render_mball(Render *re, ObjectRen *obr) } } - for(a=0; anr; a++, data+=3, nors+=3, orco+=3) { + for(a=0; anr; a++, data+=3, nors+=3) { ver= RE_findOrAddVert(obr, obr->totvert++); VECCOPY(ver->co, data); @@ -2393,7 +2393,7 @@ static void init_render_mball(Render *re, ObjectRen *obr) normalize_v3(ver->n); //if(ob->transflag & OB_NEG_SCALE) negate_v3(ver->n); - if(need_orco) ver->orco= orco; + if(need_orco) ver->orco= orco+=3; } index= dl->index; -- cgit v1.2.3 From 97576cd51b2fd5cca4de8003be0665f8d79fe2d3 Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Thu, 7 Oct 2010 10:57:21 +0000 Subject: Fix for [#22250] Retopo projects to the wrong object when multiple objects are behind. * Scaling of objects wasn't properly taken into account when projecting the verts. --- source/blender/editors/transform/transform_snap.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 5b7bcac65f2..09c04168a71 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -1301,15 +1301,18 @@ int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, E BVHTreeRayHit hit; BVHTreeFromMesh treeData; + /* local scale in normal direction */ + float local_scale = len_v3(ray_normal_local); + bvhtree_from_mesh_faces(&treeData, dm, 0.0f, 4, 6); hit.index = -1; - hit.dist = *depth; + hit.dist = *depth * (*depth == FLT_MAX ? 1.0f : local_scale); if(treeData.tree && BLI_bvhtree_ray_cast(treeData.tree, ray_start_local, ray_normal_local, 0.0f, &hit, treeData.raycast_callback, &treeData) != -1) { - if(hit.dist<=*depth) { - *depth= hit.dist; + if(hit.dist/local_scale <= *depth) { + *depth= hit.dist/local_scale; copy_v3_v3(loc, hit.co); copy_v3_v3(no, hit.no); -- cgit v1.2.3 From e9189bddb900ab86eedfb35dbf46d900a84509bb Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 7 Oct 2010 12:18:09 +0000 Subject: Fix #24180: Make duplicates real doesn't update immediatly the outliner --- source/blender/editors/object/object_add.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source/blender') diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index e0608f03274..3ae1941035d 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1010,6 +1010,9 @@ static int object_duplicates_make_real_exec(bContext *C, wmOperator *op) CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { make_object_duplilist_real(C, scene, base); + + /* dependencies were changed */ + WM_event_add_notifier(C, NC_OBJECT|ND_PARENT, base->object); } CTX_DATA_END; -- cgit v1.2.3 From e4964a347706e97f98043d80feff65769977c7bf Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 7 Oct 2010 16:41:42 +0000 Subject: Fix #24167: Timeline keyframes don't update when selecting objects from outliner Based on patch from Alexander Kuznetsov. Own changes: - Keyframes in timelime depends on active object, so timelime better be listeing to ND_OB_ACTIVE notifier rather than ND_OB_SELECT - When scene is changing in this operator NC_WINDOW notifier would be send and the whole interface would be redrawed, so no need in ND_OB_ACTIVE in this case --- source/blender/editors/space_outliner/outliner.c | 7 +++---- source/blender/editors/space_time/space_time.c | 1 + 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c index c9aac8502c4..20b5ad7a34f 100644 --- a/source/blender/editors/space_outliner/outliner.c +++ b/source/blender/editors/space_outliner/outliner.c @@ -1931,15 +1931,14 @@ static void tree_element_set_active_object(bContext *C, Scene *scene, SpaceOops scene_deselect_all(scene); ED_base_object_select(base, BA_SELECT); } - if(C) + if(C) { ED_base_object_activate(C, base); /* adds notifier */ + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); + } } if(ob!=scene->obedit) ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR|EM_DO_UNDO); - - WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, scene); - } static int tree_element_active_material(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, int set) diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c index ca7dc29ad85..0d3b0514122 100644 --- a/source/blender/editors/space_time/space_time.c +++ b/source/blender/editors/space_time/space_time.c @@ -519,6 +519,7 @@ static void time_main_area_listener(ARegion *ar, wmNotifier *wmn) case NC_SCENE: switch (wmn->data) { case ND_OB_SELECT: + case ND_OB_ACTIVE: case ND_FRAME: case ND_FRAME_RANGE: case ND_KEYINGSET: -- cgit v1.2.3 From c52c10d1781825290d56d27551b6a51b4ab85b40 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 7 Oct 2010 21:25:05 +0000 Subject: append was using a freed Main pointer to refer to the curlib when instancing group objects and centering objects around the cursor. --- source/blender/blenloader/intern/readfile.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index f24de9c605d..0eb25a6b894 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -12433,25 +12433,29 @@ static void library_append_end(const bContext *C, Main *mainl, FileData **fd, in { Main *mainvar= CTX_data_main(C); Scene *scene= CTX_data_scene(C); + Library *curlib; /* make main consistent */ expand_main(*fd, mainl); /* do this when expand found other libs */ read_libraries(*fd, &(*fd)->mainlist); + + curlib= mainl->curlib; /* make the lib path relative if required */ if(flag & FILE_RELPATH) { /* use the full path, this could have been read by other library even */ - BLI_strncpy(mainl->curlib->name, mainl->curlib->filepath, sizeof(mainl->curlib->name)); + BLI_strncpy(curlib->name, curlib->filepath, sizeof(curlib->name)); /* uses current .blend file as reference */ - BLI_path_rel(mainl->curlib->name, G.sce); + BLI_path_rel(curlib->name, G.sce); } blo_join_main(&(*fd)->mainlist); mainvar= (*fd)->mainlist.first; + mainl= NULL; /* blo_join_main free's mainl, cant use anymore */ lib_link_all(*fd, mainvar); lib_verify_nodetree(mainvar, 0); @@ -12466,7 +12470,7 @@ static void library_append_end(const bContext *C, Main *mainl, FileData **fd, in if (flag & FILE_LINK) { give_base_to_objects(mainvar, scene, NULL, 0); } else { - give_base_to_objects(mainvar, scene, mainl->curlib, 1); + give_base_to_objects(mainvar, scene, curlib, 1); } if (flag & FILE_GROUP_INSTANCE) { @@ -12486,7 +12490,7 @@ static void library_append_end(const bContext *C, Main *mainl, FileData **fd, in *fd = NULL; } - append_do_cursor(scene, mainl->curlib, flag); + append_do_cursor(scene, curlib, flag); } void BLO_library_append_end(const bContext *C, struct Main *mainl, BlendHandle** bh, int idcode, short flag) -- cgit v1.2.3 From afa1bf33fb48db48fb909e4853094f2d962f8327 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 7 Oct 2010 23:17:14 +0000 Subject: bugfix [#21610] alt-r for bone (reset rotation) doesnt work in weight painting mode pose operators now run in weightpaint mode when the weight paint objects pose armature is in pose mode. --- source/blender/editors/armature/editarmature.c | 18 +++--- source/blender/editors/armature/poseSlide.c | 2 +- source/blender/editors/armature/poselib.c | 16 ++--- source/blender/editors/armature/poseobject.c | 72 ++++++++++++++++------- source/blender/editors/include/ED_armature.h | 1 + source/blender/editors/object/object_constraint.c | 9 +-- source/blender/editors/screen/screen_context.c | 23 ++++---- source/blender/editors/screen/screen_ops.c | 5 +- 8 files changed, 92 insertions(+), 54 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index ead5d44d393..26a89c4de02 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -558,7 +558,7 @@ static void applyarmature_fix_boneparents (Scene *scene, Object *armob) static int apply_armature_pose2bones_exec (bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_active_object(C); // must be active object, not edit-object + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); // must be active object, not edit-object bArmature *arm= get_armature(ob); bPose *pose; bPoseChannel *pchan; @@ -658,7 +658,7 @@ void POSE_OT_armature_apply (wmOperatorType *ot) static int pose_visual_transform_apply_exec (bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_active_object(C); // must be active object, not edit-object + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); // must be active object, not edit-object /* don't check if editmode (should be done by caller) */ if (ob->type!=OB_ARMATURE) @@ -1389,7 +1389,7 @@ static int pose_setflag_exec (bContext *C, wmOperator *op) CTX_DATA_END; /* note, notifier might evolve */ - WM_event_add_notifier(C, NC_OBJECT|ND_POSE, CTX_data_active_object(C)); + WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ED_object_pose_armature(CTX_data_active_object(C))); return OPERATOR_FINISHED; } @@ -4917,7 +4917,7 @@ void create_vgroups_from_armature(Scene *scene, Object *ob, Object *par, int mod static int pose_clear_scale_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); short autokey = 0; /* only clear those channels that are not locked */ @@ -4985,7 +4985,7 @@ void POSE_OT_scale_clear(wmOperatorType *ot) static int pose_clear_loc_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); short autokey = 0; /* only clear those channels that are not locked */ @@ -5054,7 +5054,7 @@ void POSE_OT_loc_clear(wmOperatorType *ot) static int pose_clear_rot_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); short autokey = 0; /* only clear those channels that are not locked */ @@ -5306,7 +5306,7 @@ void POSE_OT_select_all(wmOperatorType *ot) static int pose_select_parent_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); bPoseChannel *pchan,*parent; /* Determine if there is an active bone */ @@ -5381,7 +5381,7 @@ static int hide_unselected_pose_bone(Object *ob, Bone *bone, void *ptr) /* active object is armature in posemode, poll checked */ static int pose_hide_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); bArmature *arm= ob->data; if(RNA_boolean_get(op->ptr, "unselected")) @@ -5431,7 +5431,7 @@ static int show_pose_bone(Object *ob, Bone *bone, void *ptr) /* active object is armature in posemode, poll checked */ static int pose_reveal_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); bArmature *arm= ob->data; bone_looper(ob, arm->bonebase.first, NULL, show_pose_bone); diff --git a/source/blender/editors/armature/poseSlide.c b/source/blender/editors/armature/poseSlide.c index 8d8f1bf24ee..482d97811a3 100644 --- a/source/blender/editors/armature/poseSlide.c +++ b/source/blender/editors/armature/poseSlide.c @@ -119,7 +119,7 @@ static int pose_slide_init (bContext *C, wmOperator *op, short mode) /* get info from context */ pso->scene= CTX_data_scene(C); - pso->ob= CTX_data_active_object(C); + pso->ob= ED_object_pose_armature(CTX_data_active_object(C)); pso->arm= (pso->ob)? pso->ob->data : NULL; pso->ar= CTX_wm_region(C); /* only really needed when doing modal() */ diff --git a/source/blender/editors/armature/poselib.c b/source/blender/editors/armature/poselib.c index 6083616044e..9292c92294b 100644 --- a/source/blender/editors/armature/poselib.c +++ b/source/blender/editors/armature/poselib.c @@ -270,7 +270,7 @@ static KeyingSet *poselib_ks_locrotscale = NULL; /* the only keyingset we'll ne static void poselib_add_menu_invoke__replacemenu (bContext *C, uiLayout *layout, void *arg) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); bAction *act= ob->poselib; TimeMarker *marker; @@ -293,7 +293,7 @@ static void poselib_add_menu_invoke__replacemenu (bContext *C, uiLayout *layout, static int poselib_add_menu_invoke (bContext *C, wmOperator *op, wmEvent *evt) { Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); bArmature *arm= (ob) ? ob->data : NULL; bPose *pose= (ob) ? ob->pose : NULL; uiPopupMenu *pup; @@ -329,7 +329,7 @@ static int poselib_add_menu_invoke (bContext *C, wmOperator *op, wmEvent *evt) static int poselib_add_exec (bContext *C, wmOperator *op) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); bAction *act = poselib_validate(ob); bArmature *arm= (ob) ? ob->data : NULL; bPose *pose= (ob) ? ob->pose : NULL; @@ -404,7 +404,7 @@ void POSELIB_OT_pose_add (wmOperatorType *ot) static EnumPropertyItem *poselib_stored_pose_itemf(bContext *C, PointerRNA *ptr, int *free) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); bAction *act= (ob) ? ob->poselib : NULL; TimeMarker *marker; EnumPropertyItem *item= NULL, item_tmp; @@ -436,7 +436,7 @@ static EnumPropertyItem *poselib_stored_pose_itemf(bContext *C, PointerRNA *ptr, static int poselib_remove_exec (bContext *C, wmOperator *op) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); bAction *act= (ob) ? ob->poselib : NULL; TimeMarker *marker; FCurve *fcu; @@ -505,7 +505,7 @@ void POSELIB_OT_pose_remove (wmOperatorType *ot) static int poselib_rename_invoke (bContext *C, wmOperator *op, wmEvent *evt) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); bAction *act= (ob) ? ob->poselib : NULL; TimeMarker *marker; @@ -533,7 +533,7 @@ static int poselib_rename_invoke (bContext *C, wmOperator *op, wmEvent *evt) static int poselib_rename_exec (bContext *C, wmOperator *op) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); bAction *act= (ob) ? ob->poselib : NULL; TimeMarker *marker; char newname[64]; @@ -1237,7 +1237,7 @@ static int poselib_preview_handle_event (bContext *C, wmOperator *op, wmEvent *e static void poselib_preview_init_data (bContext *C, wmOperator *op) { tPoseLib_PreviewData *pld; - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); int pose_index = RNA_int_get(op->ptr, "pose_index"); /* set up preview state info */ diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index b94b3e68318..4aff2f1e915 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -76,6 +76,38 @@ static void error(const char *dummy) {}; static void BIF_undo_push(const char *dummy) {} /* ************* XXX *************** */ + +static int object_pose_context(Object *ob) +{ + if( (ob) && + (ob->type == OB_ARMATURE) && + (ob->pose) && + (ob->mode & OB_MODE_POSE) + ) { + return 1; + } + else { + return 0; + } +} + +Object *ED_object_pose_armature(Object *ob) +{ + if(ob==NULL) + return NULL; + + if(object_pose_context(ob)) + return ob; + + ob= modifiers_isDeformedByArmature(ob); + + if(object_pose_context(ob)) + return ob; + + return NULL; +} + + /* This function is used to indicate that a bone is selected and needs keyframes inserted */ void set_pose_keys (Object *ob) { @@ -220,7 +252,7 @@ static int pose_calculate_paths_exec (bContext *C, wmOperator *op) if (sa->spacetype == SPACE_BUTS) ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; else - ob= CTX_data_active_object(C); + ob= ED_object_pose_armature(CTX_data_active_object(C)); if (ELEM(NULL, ob, ob->pose)) return OPERATOR_CANCELLED; @@ -296,7 +328,7 @@ static int pose_clear_paths_exec (bContext *C, wmOperator *op) if (sa->spacetype == SPACE_BUTS) ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; else - ob= CTX_data_active_object(C); + ob= ED_object_pose_armature(CTX_data_active_object(C)); /* only continue if there's an object */ if ELEM(NULL, ob, ob->pose) @@ -330,7 +362,7 @@ void POSE_OT_paths_clear (wmOperatorType *ot) static int pose_select_constraint_target_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); bArmature *arm= ob->data; bConstraint *con; int found= 0; @@ -390,7 +422,7 @@ void POSE_OT_select_constraint_target(wmOperatorType *ot) static int pose_select_hierarchy_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); bArmature *arm= ob->data; Bone *curbone, *pabone, *chbone; int direction = RNA_enum_get(op->ptr, "direction"); @@ -570,7 +602,7 @@ static short pose_select_same_layer (bContext *C, Object *ob, short extend) static int pose_select_grouped_exec (bContext *C, wmOperator *op) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); short extend= RNA_boolean_get(op->ptr, "extend"); short changed = 0; @@ -856,7 +888,7 @@ void free_posebuf(void) static int pose_copy_exec (bContext *C, wmOperator *op) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); /* sanity checking */ if ELEM(NULL, ob, ob->pose) { @@ -895,7 +927,7 @@ void POSE_OT_copy (wmOperatorType *ot) static int pose_paste_exec (bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); bPoseChannel *chan, *pchan; int flip= RNA_boolean_get(op->ptr, "flipped"); @@ -1077,7 +1109,7 @@ static int pose_group_add_exec (bContext *C, wmOperator *op) if (sa->spacetype == SPACE_BUTS) ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; else - ob= CTX_data_active_object(C); + ob= ED_object_pose_armature(CTX_data_active_object(C)); /* only continue if there's an object */ if (ob == NULL) @@ -1117,7 +1149,7 @@ static int pose_group_remove_exec (bContext *C, wmOperator *op) if (sa->spacetype == SPACE_BUTS) ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; else - ob= CTX_data_active_object(C); + ob= ED_object_pose_armature(CTX_data_active_object(C)); /* only continue if there's an object */ if (ob == NULL) @@ -1165,7 +1197,7 @@ static int pose_groups_menu_invoke (bContext *C, wmOperator *op, wmEvent *evt) if (sa->spacetype == SPACE_BUTS) ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; else - ob= CTX_data_active_object(C); + ob= ED_object_pose_armature(CTX_data_active_object(C)); /* only continue if there's an object, and a pose there too */ if (ELEM(NULL, ob, ob->pose)) @@ -1215,7 +1247,7 @@ static int pose_group_assign_exec (bContext *C, wmOperator *op) if (sa->spacetype == SPACE_BUTS) ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; else - ob= CTX_data_active_object(C); + ob= ED_object_pose_armature(CTX_data_active_object(C)); /* only continue if there's an object, and a pose there too */ if (ELEM(NULL, ob, ob->pose)) @@ -1280,7 +1312,7 @@ static int pose_group_unassign_exec (bContext *C, wmOperator *op) if (sa->spacetype == SPACE_BUTS) ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; else - ob= CTX_data_active_object(C); + ob= ED_object_pose_armature(CTX_data_active_object(C)); /* only continue if there's an object, and a pose there too */ if (ELEM(NULL, ob, ob->pose)) @@ -1352,7 +1384,7 @@ static int pose_group_select_exec (bContext *C, wmOperator *op) if (sa->spacetype == SPACE_BUTS) ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; else - ob= CTX_data_active_object(C); + ob= ED_object_pose_armature(CTX_data_active_object(C)); /* only continue if there's an object, and a pose there too */ if (ELEM(NULL, ob, ob->pose)) @@ -1390,7 +1422,7 @@ static int pose_group_deselect_exec (bContext *C, wmOperator *op) if (sa->spacetype == SPACE_BUTS) ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; else - ob= CTX_data_active_object(C); + ob= ED_object_pose_armature(CTX_data_active_object(C)); /* only continue if there's an object, and a pose there too */ if (ELEM(NULL, ob, ob->pose)) @@ -1423,7 +1455,7 @@ void POSE_OT_group_deselect (wmOperatorType *ot) static int pose_flip_names_exec (bContext *C, wmOperator *op) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); bArmature *arm; /* paranoia checks */ @@ -1468,7 +1500,7 @@ void POSE_OT_flip_names (wmOperatorType *ot) static int pose_autoside_names_exec (bContext *C, wmOperator *op) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); bArmature *arm; char newname[32]; short axis= RNA_enum_get(op->ptr, "axis"); @@ -1567,7 +1599,7 @@ void pose_activate_flipped_bone(Scene *scene) /* Present a popup to get the layers that should be used */ static int pose_armature_layers_invoke (bContext *C, wmOperator *op, wmEvent *evt) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); bArmature *arm= (ob)? ob->data : NULL; PointerRNA ptr; int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */ @@ -1588,7 +1620,7 @@ static int pose_armature_layers_invoke (bContext *C, wmOperator *op, wmEvent *ev /* Set the visible layers for the active armature (edit and pose modes) */ static int pose_armature_layers_exec (bContext *C, wmOperator *op) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); bArmature *arm= (ob)? ob->data : NULL; PointerRNA ptr; int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */ @@ -1677,7 +1709,7 @@ static int pose_bone_layers_invoke (bContext *C, wmOperator *op, wmEvent *evt) /* Set the visible layers for the active armature (edit and pose modes) */ static int pose_bone_layers_exec (bContext *C, wmOperator *op) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); bArmature *arm= (ob)? ob->data : NULL; PointerRNA ptr; int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */ @@ -1798,7 +1830,7 @@ void ARMATURE_OT_bone_layers (wmOperatorType *ot) static int pose_flip_quats_exec (bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, "LocRotScale"); /* loop through all selected pchans, flipping and keying (as needed) */ diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 474b50540d8..809b86d65f3 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -141,6 +141,7 @@ void ED_armature_bone_rename(struct bArmature *arm, char *oldnamep, char *newnam void undo_push_armature(struct bContext *C, char *name); /* poseobject.c */ +struct Object *ED_object_pose_armature(struct Object *ob); void ED_armature_exit_posemode(struct bContext *C, struct Base *base); void ED_armature_enter_posemode(struct bContext *C, struct Base *base); int ED_pose_channel_in_IK_chain(struct Object *ob, struct bPoseChannel *pchan); diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index f5d87df10a1..fd3c8b165c0 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -65,6 +65,7 @@ #include "RNA_enum_types.h" #include "ED_object.h" +#include "ED_armature.h" #include "ED_screen.h" #include "UI_interface.h" @@ -935,7 +936,7 @@ static int pose_constraints_clear_exec(bContext *C, wmOperator *op) { Main *bmain= CTX_data_main(C); Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); /* free constraints for all selected bones */ CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones) @@ -1364,7 +1365,7 @@ static int object_constraint_add_exec(bContext *C, wmOperator *op) /* dummy operator callback */ static int pose_constraint_add_exec(bContext *C, wmOperator *op) { - Object *ob= ED_object_active_context(C); + Object *ob= ED_object_pose_armature(ED_object_active_context(C)); int type= RNA_enum_get(op->ptr, "type"); short with_targets= 0; @@ -1467,7 +1468,7 @@ void POSE_OT_constraint_add_with_targets(wmOperatorType *ot) /* present menu with options + validation for targets to use */ static int pose_ik_add_invoke(bContext *C, wmOperator *op, wmEvent *evt) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); bPoseChannel *pchan= get_active_posechannel(ob); bConstraint *con= NULL; @@ -1551,7 +1552,7 @@ void POSE_OT_ik_add(wmOperatorType *ot) /* remove IK constraints from selected bones */ static int pose_ik_clear_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); /* only remove IK Constraints */ CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones) diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index fbc83b1de65..b619398d985 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -209,14 +209,15 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult } } else if(CTX_data_equals(member, "visible_pose_bones")) { - bArmature *arm= (obact) ? obact->data : NULL; + Object *obpose= ED_object_pose_armature(obact); + bArmature *arm= (obpose) ? obpose->data : NULL; bPoseChannel *pchan; - if (obact && obact->pose && arm) { - for (pchan= obact->pose->chanbase.first; pchan; pchan= pchan->next) { + if (obpose && obpose->pose && arm) { + for (pchan= obpose->pose->chanbase.first; pchan; pchan= pchan->next) { /* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */ if ((pchan->bone) && (arm->layer & pchan->bone->layer) && !(pchan->bone->flag & BONE_HIDDEN_P)) { - CTX_data_list_add(result, &obact->id, &RNA_PoseBone, pchan); + CTX_data_list_add(result, &obpose->id, &RNA_PoseBone, pchan); } } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); @@ -224,15 +225,16 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult } } else if(CTX_data_equals(member, "selected_pose_bones")) { - bArmature *arm= (obact) ? obact->data : NULL; + Object *obpose= ED_object_pose_armature(obact); + bArmature *arm= (obpose) ? obpose->data : NULL; bPoseChannel *pchan; - if (obact && obact->pose && arm) { - for (pchan= obact->pose->chanbase.first; pchan; pchan= pchan->next) { + if (obpose && obpose->pose && arm) { + for (pchan= obpose->pose->chanbase.first; pchan; pchan= pchan->next) { /* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */ if ((pchan->bone) && (arm->layer & pchan->bone->layer) && !(pchan->bone->flag & BONE_HIDDEN_P)) { if (pchan->bone->flag & BONE_SELECTED || pchan->bone == arm->act_bone) - CTX_data_list_add(result, &obact->id, &RNA_PoseBone, pchan); + CTX_data_list_add(result, &obpose->id, &RNA_PoseBone, pchan); } } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); @@ -258,10 +260,11 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult } else if(CTX_data_equals(member, "active_pose_bone")) { bPoseChannel *pchan; + Object *obpose= ED_object_pose_armature(obact); - pchan= get_active_posechannel(obact); + pchan= get_active_posechannel(obpose); if (pchan) { - CTX_data_pointer_set(result, &obact->id, &RNA_PoseBone, pchan); + CTX_data_pointer_set(result, &obpose->id, &RNA_PoseBone, pchan); return 1; } } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 7638d576d9d..7b9bad5945d 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -56,6 +56,7 @@ #include "ED_util.h" #include "ED_screen.h" #include "ED_object.h" +#include "ED_armature.h" #include "ED_screen_types.h" #include "ED_keyframes_draw.h" @@ -259,8 +260,8 @@ int ED_operator_posemode(bContext *C) Object *obact= CTX_data_active_object(C); Object *obedit= CTX_data_edit_object(C); - if ((obact != obedit) && (obact) && (obact->type==OB_ARMATURE)) - return (obact->mode & OB_MODE_POSE)!=0; + if ((obact != obedit) && ED_object_pose_armature(obact)) + return 1; return 0; } -- cgit v1.2.3 From c6e2e7aa9374427ae114fcc532e7f2c8a8977874 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 8 Oct 2010 02:08:11 +0000 Subject: move tracking functions into math_rotation.c (no functional changes) --- source/blender/blenkernel/intern/lattice.c | 65 +++++---------------------- source/blender/blenlib/BLI_math_rotation.h | 3 ++ source/blender/blenlib/intern/math_rotation.c | 62 +++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 55 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 1390f0dbd56..71e5049f2cc 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -599,16 +599,6 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C } #endif - - static float q_x90d[4] = {0.70710676908493, 0.70710676908493, 0.0, 0.0}; // float rot_axis[3]= {1,0,0}; axis_angle_to_quat(q, rot_axis, 90 * (M_PI / 180)); - static float q_y90d[4] = {0.70710676908493, 0.0, 0.70710676908493, 0.0}; // float rot_axis[3]= {0,1,0}; axis_angle_to_quat(q, rot_axis, 90 * (M_PI / 180)); - static float q_z90d[4] = {0.70710676908493, 0.0, 0.0, 0.70710676908493}; // float rot_axis[3]= {0,0,2}; axis_angle_to_quat(q, rot_axis, 90 * (M_PI / 180)); - - static float q_nx90d[4] = {0.70710676908493, -0.70710676908493, 0.0, 0.0}; // float rot_axis[3]= {1,0,0}; axis_angle_to_quat(q, rot_axis, -90 * (M_PI / 180)); - static float q_ny90d[4] = {0.70710676908493, 0.0, -0.70710676908493, 0.0}; // float rot_axis[3]= {0,1,0}; axis_angle_to_quat(q, rot_axis, -90 * (M_PI / 180)); - static float q_nz90d[4] = {0.70710676908493, 0.0, 0.0, -0.70710676908493}; // float rot_axis[3]= {0,0,2}; axis_angle_to_quat(q, rot_axis, -90 * (M_PI / 180)); - - if(cd->no_rot_axis) { /* set by caller */ /* this is not exactly the same as 2.4x, since the axis is having rotation removed rather then @@ -635,53 +625,18 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C * Notice X,Y,Z Up all have light colors and each ordered CCW. * * Now for Neg Up XYZ, the colors are all dark, and ordered clockwise - Campbell + * + * note: moved functions into quat_apply_track/vec_apply_track * */ + copy_qt_qt(quat, new_quat); + copy_v3_v3(cent, co); + + /* zero the axis which is not used, + * the big block of text above now applies to these 3 lines */ + quat_apply_track(quat, axis-1); + vec_apply_track(cent, axis-1); + cent[axis < 4 ? axis-1 : axis-4]= 0.0f; - switch(axis) { - case MOD_CURVE_POSX: - mul_qt_qtqt(quat, new_quat, q_y90d); - - cent[0]= 0.0; - cent[1]= co[2]; - cent[2]= co[1]; - break; - case MOD_CURVE_NEGX: - mul_qt_qtqt(quat, new_quat, q_ny90d); - - cent[0]= 0.0; - cent[1]= -co[1]; - cent[2]= co[2]; - - break; - case MOD_CURVE_POSY: - mul_qt_qtqt(quat, new_quat, q_x90d); - - cent[0]= co[2]; - cent[1]= 0.0; - cent[2]= -co[0]; - break; - case MOD_CURVE_NEGY: - mul_qt_qtqt(quat, new_quat, q_nx90d); - - cent[0]= -co[0]; - cent[1]= 0.0; - cent[2]= -co[2]; - break; - case MOD_CURVE_POSZ: - mul_qt_qtqt(quat, new_quat, q_z90d); - - cent[0]= co[1]; - cent[1]= -co[0]; - cent[2]= 0.0; - break; - case MOD_CURVE_NEGZ: - mul_qt_qtqt(quat, new_quat, q_nz90d); - - cent[0]= co[0]; - cent[1]= -co[1]; - cent[2]= 0.0; - break; - } /* scale if enabled */ if(cu->flag & CU_PATH_RADIUS) diff --git a/source/blender/blenlib/BLI_math_rotation.h b/source/blender/blenlib/BLI_math_rotation.h index 1b3f4dced02..4b33efc5578 100644 --- a/source/blender/blenlib/BLI_math_rotation.h +++ b/source/blender/blenlib/BLI_math_rotation.h @@ -169,6 +169,9 @@ void mul_v3m3_dq(float r[3], float R[3][3], DualQuat *dq); void mat4_to_dquat(DualQuat *r, float base[4][4], float M[4][4]); void dquat_to_mat4(float R[4][4], DualQuat *dq); +void quat_apply_track(float quat[4], short axis); +void vec_apply_track(float vec[3], short axis); + float lens_to_angle(float lens); float angle_to_lens(float angle); diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c index b8cef511293..4e555b02c2b 100644 --- a/source/blender/blenlib/intern/math_rotation.c +++ b/source/blender/blenlib/intern/math_rotation.c @@ -1530,6 +1530,68 @@ void copy_dq_dq(DualQuat *dq1, DualQuat *dq2) memcpy(dq1, dq2, sizeof(DualQuat)); } +/* axis matches eTrackToAxis_Modes */ +void quat_apply_track(float quat[4], short axis) +{ + /* axis calculated as follows */ + /* float axis[3]= {1,0,0}; axis_angle_to_quat(q, axis, 90 * (M_PI / 180)); + float axis[3]= {0,1,0}; axis_angle_to_quat(q, axis, 90 * (M_PI / 180)); + float axis[3]= {0,0,2}; axis_angle_to_quat(q, axis, 90 * (M_PI / 180)); + float axis[3]= {1,0,0}; axis_angle_to_quat(q, axis, -90 * (M_PI / 180)); + float axis[3]= {0,1,0}; axis_angle_to_quat(q, axis, -90 * (M_PI / 180)); + float axis[3]= {0,0,2}; axis_angle_to_quat(q, axis, -90 * (M_PI / 180)); */ + + /* notice x/y flipped intentionally */ + const float quat_track[][4]= {{0.70710676908493, 0.0, 0.70710676908493, 0.0}, /* pos-y */ + {0.70710676908493, 0.70710676908493, 0.0, 0.0}, /* pos-x */ + {0.70710676908493, 0.0, 0.0, 0.70710676908493}, /* pos-z */ + {0.70710676908493, 0.0, -0.70710676908493, 0.0}, /* neg-y */ + {0.70710676908493, -0.70710676908493, 0.0, 0.0}, /* neg-x */ + {0.70710676908493, 0.0, 0.0, -0.70710676908493}};/* neg-z */ + + mul_qt_qtqt(quat, quat, quat_track[axis]); +} + +void vec_apply_track(float vec[3], short axis) +{ + float tvec[3]; + + copy_v3_v3(tvec, vec); + + switch(axis) { + case 0: /* pos-x */ + /* vec[0]= 0.0; */ + vec[1]= tvec[2]; + vec[2]= tvec[1]; + break; + case 1: /* pos-y */ + vec[0]= tvec[2]; + /* vec[1]= 0.0; */ + vec[2]= -tvec[0]; + break; + case 2: /* pos-z */ + vec[0]= tvec[1]; + vec[1]= -tvec[0]; + // vec[2]= 0.0; */ + break; + case 3: /* neg-x */ + /* vec[0]= 0.0; */ + vec[1]= -tvec[1]; + vec[2]= tvec[2]; + break; + case 4: /* neg-y */ + vec[0]= -tvec[0]; + /* vec[1]= 0.0; */ + vec[2]= -tvec[2]; + break; + case 5: /* neg-z */ + vec[0]= tvec[0]; + vec[1]= -tvec[1]; + /* vec[2]= 0.0; */ + break; + } +} + /* lense/angle conversion (radians) */ float lens_to_angle(float lens) { -- cgit v1.2.3 From 28b264de67b99023e2e42b895804d8e6d88798dd Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 8 Oct 2010 02:48:24 +0000 Subject: Fix #23358: template_curve_mapping doesn't work in split views --- source/blender/editors/interface/interface_layout.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source/blender') diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 4a9d7a0f6f3..45b38a8c9a9 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -2169,6 +2169,7 @@ uiLayout *uiLayoutSplit(uiLayout *layout, float percentage, int align) split->litem.enabled= 1; split->litem.context= layout->context; split->litem.space= layout->root->style->columnspace; + split->litem.w= layout->w; split->percentage= percentage; BLI_addtail(&layout->items, split); -- cgit v1.2.3 From 5e232548d3d3362ba5f2af7807237bc7d6b672d6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 8 Oct 2010 03:50:01 +0000 Subject: fix for error in track rotation, found while looking into adding an up axis to this function. --- source/blender/blenlib/intern/math_rotation.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c index 4e555b02c2b..be383fdc73c 100644 --- a/source/blender/blenlib/intern/math_rotation.c +++ b/source/blender/blenlib/intern/math_rotation.c @@ -1542,10 +1542,10 @@ void quat_apply_track(float quat[4], short axis) float axis[3]= {0,0,2}; axis_angle_to_quat(q, axis, -90 * (M_PI / 180)); */ /* notice x/y flipped intentionally */ - const float quat_track[][4]= {{0.70710676908493, 0.0, 0.70710676908493, 0.0}, /* pos-y */ + const float quat_track[][4]= {{0.70710676908493, 0.0, -0.70710676908493, 0.0}, /* pos-y */ {0.70710676908493, 0.70710676908493, 0.0, 0.0}, /* pos-x */ {0.70710676908493, 0.0, 0.0, 0.70710676908493}, /* pos-z */ - {0.70710676908493, 0.0, -0.70710676908493, 0.0}, /* neg-y */ + {0.70710676908493, 0.0, 0.70710676908493, 0.0}, /* neg-y */ {0.70710676908493, -0.70710676908493, 0.0, 0.0}, /* neg-x */ {0.70710676908493, 0.0, 0.0, -0.70710676908493}};/* neg-z */ @@ -1562,7 +1562,7 @@ void vec_apply_track(float vec[3], short axis) case 0: /* pos-x */ /* vec[0]= 0.0; */ vec[1]= tvec[2]; - vec[2]= tvec[1]; + vec[2]= -tvec[1]; break; case 1: /* pos-y */ vec[0]= tvec[2]; @@ -1577,7 +1577,7 @@ void vec_apply_track(float vec[3], short axis) case 3: /* neg-x */ /* vec[0]= 0.0; */ vec[1]= -tvec[1]; - vec[2]= tvec[2]; + vec[2]= -tvec[2]; break; case 4: /* neg-y */ vec[0]= -tvec[0]; -- cgit v1.2.3 From 65b0893df0c82b04701f5f39c725df983c19f0c7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 8 Oct 2010 07:29:08 +0000 Subject: bugfix [#21483] Twisting when Dupliframing a Surface Circle (Nurbs) along a Curve. use the curve's twist for follow path constraint and parent-path. --- source/blender/blenkernel/intern/constraint.c | 16 ++++++--- source/blender/blenkernel/intern/lattice.c | 2 +- source/blender/blenkernel/intern/object.c | 10 ++++-- source/blender/blenlib/BLI_math_rotation.h | 2 +- source/blender/blenlib/intern/math_rotation.c | 48 ++++++++++++++------------- 5 files changed, 45 insertions(+), 33 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index fe69f13bbda..3df395244f4 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -1201,7 +1201,7 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr if (VALID_CONS_TARGET(ct)) { Curve *cu= ct->tar->data; - float q[4], vec[4], dir[3], quat[4], radius, x1; + float vec[4], dir[3], radius; float totmat[4][4]; float curvetime; @@ -1217,7 +1217,8 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr makeDispListCurveTypes(cob->scene, ct->tar, 0); if (cu->path && cu->path->data) { - if ((data->followflag & FOLLOWPATH_STATIC) == 0) { + float quat[4]; + if ((data->followflag & FOLLOWPATH_STATIC) == 0) { /* animated position along curve depending on time */ if (cob->scene) curvetime= bsystem_time(cob->scene, ct->tar, cu->ctime, 0.0) - data->offset; @@ -1238,8 +1239,10 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr curvetime= data->offset_fac; } - if ( where_on_path(ct->tar, curvetime, vec, dir, NULL, &radius, NULL) ) { + if ( where_on_path(ct->tar, curvetime, vec, dir, (data->followflag & FOLLOWPATH_FOLLOW) ? quat : NULL, &radius, NULL) ) { /* quat_pt is quat or NULL*/ if (data->followflag & FOLLOWPATH_FOLLOW) { +#if 0 + float x1, q[4]; vec_to_quat(quat, dir, (short)data->trackflag, (short)data->upflag); normalize_v3(dir); @@ -1249,10 +1252,13 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr q[2]= -x1*dir[1]; q[3]= -x1*dir[2]; mul_qt_qtqt(quat, q, quat); - +#else + quat_apply_track(quat, data->trackflag, data->upflag); +#endif + quat_to_mat4(totmat, quat); } - + if (data->followflag & FOLLOWPATH_RADIUS) { float tmat[4][4], rmat[4][4]; scale_m4_fl(tmat, radius); diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 71e5049f2cc..638cab58229 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -633,7 +633,7 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C /* zero the axis which is not used, * the big block of text above now applies to these 3 lines */ - quat_apply_track(quat, axis-1); + quat_apply_track(quat, axis-1, (axis==1 || axis==3) ? 1:0); /* up flag is a dummy, set so no rotation is done */ vec_apply_track(cent, axis-1); cent[axis < 4 ? axis-1 : axis-4]= 0.0f; diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index d9ee67920eb..0c437db335b 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1791,9 +1791,10 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4]) /* vec: 4 items! */ - if( where_on_path(par, ctime, vec, dir, NULL, &radius, NULL) ) { + if( where_on_path(par, ctime, vec, dir, cu->flag & CU_FOLLOW ? quat:NULL, &radius, NULL) ) { if(cu->flag & CU_FOLLOW) { +#if 0 vec_to_quat( quat,dir, ob->trackflag, ob->upflag); /* the tilt */ @@ -1804,8 +1805,11 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4]) q[2]= -x1*dir[1]; q[3]= -x1*dir[2]; mul_qt_qtqt(quat, q, quat); - - quat_to_mat4( mat,quat); +#else + quat_apply_track(quat, ob->trackflag, ob->upflag); +#endif + + quat_to_mat4(mat,quat); } if(cu->flag & CU_PATH_RADIUS) { diff --git a/source/blender/blenlib/BLI_math_rotation.h b/source/blender/blenlib/BLI_math_rotation.h index 4b33efc5578..321fd28a62f 100644 --- a/source/blender/blenlib/BLI_math_rotation.h +++ b/source/blender/blenlib/BLI_math_rotation.h @@ -169,7 +169,7 @@ void mul_v3m3_dq(float r[3], float R[3][3], DualQuat *dq); void mat4_to_dquat(DualQuat *r, float base[4][4], float M[4][4]); void dquat_to_mat4(float R[4][4], DualQuat *dq); -void quat_apply_track(float quat[4], short axis); +void quat_apply_track(float quat[4], short axis, short upflag); void vec_apply_track(float vec[3], short axis); float lens_to_angle(float lens); diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c index be383fdc73c..c4f12a5efc1 100644 --- a/source/blender/blenlib/intern/math_rotation.c +++ b/source/blender/blenlib/intern/math_rotation.c @@ -1531,25 +1531,27 @@ void copy_dq_dq(DualQuat *dq1, DualQuat *dq2) } /* axis matches eTrackToAxis_Modes */ -void quat_apply_track(float quat[4], short axis) -{ - /* axis calculated as follows */ - /* float axis[3]= {1,0,0}; axis_angle_to_quat(q, axis, 90 * (M_PI / 180)); - float axis[3]= {0,1,0}; axis_angle_to_quat(q, axis, 90 * (M_PI / 180)); - float axis[3]= {0,0,2}; axis_angle_to_quat(q, axis, 90 * (M_PI / 180)); - float axis[3]= {1,0,0}; axis_angle_to_quat(q, axis, -90 * (M_PI / 180)); - float axis[3]= {0,1,0}; axis_angle_to_quat(q, axis, -90 * (M_PI / 180)); - float axis[3]= {0,0,2}; axis_angle_to_quat(q, axis, -90 * (M_PI / 180)); */ - - /* notice x/y flipped intentionally */ - const float quat_track[][4]= {{0.70710676908493, 0.0, -0.70710676908493, 0.0}, /* pos-y */ - {0.70710676908493, 0.70710676908493, 0.0, 0.0}, /* pos-x */ - {0.70710676908493, 0.0, 0.0, 0.70710676908493}, /* pos-z */ - {0.70710676908493, 0.0, 0.70710676908493, 0.0}, /* neg-y */ - {0.70710676908493, -0.70710676908493, 0.0, 0.0}, /* neg-x */ - {0.70710676908493, 0.0, 0.0, -0.70710676908493}};/* neg-z */ - +void quat_apply_track(float quat[4], short axis, short upflag) +{ + /* rotations are hard coded to match vec_to_quat */ + const float quat_track[][4]= {{0.70710676908493, 0.0, -0.70710676908493, 0.0}, /* pos-y90 */ + {0.5, 0.5, 0.5, 0.5}, /* Quaternion((1,0,0), radians(90)) * Quaternion((0,1,0), radians(90)) */ + {0.70710676908493, 0.0, 0.0, 0.70710676908493}, /* pos-z90 */ + {0.70710676908493, 0.0, 0.70710676908493, 0.0}, /* neg-y90 */ + {0.5, -0.5, -0.5, 0.5}, /* Quaternion((1,0,0), radians(-90)) * Quaternion((0,1,0), radians(-90)) */ + {1, 0, 0, 0}};/* no rotation */ + mul_qt_qtqt(quat, quat, quat_track[axis]); + + if(axis>2) + axis= axis-3; + + /* 90d rotation when the second */ + if(upflag != (2-axis)>>1) { // [0->1, 1->0, 2->0] + float q[4]= {0.70710676908493, 0, 0, 0}; + q[axis+1] = ((axis==1)) ? 0.70710676908493 : -0.70710676908493; /* flip non Y axis */ + mul_qt_qtqt(quat, quat, q); + } } void vec_apply_track(float vec[3], short axis) @@ -1565,9 +1567,9 @@ void vec_apply_track(float vec[3], short axis) vec[2]= -tvec[1]; break; case 1: /* pos-y */ - vec[0]= tvec[2]; + /* vec[0]= tvec[0]; */ /* vec[1]= 0.0; */ - vec[2]= -tvec[0]; + /* vec[2]= tvec[2]; */ break; case 2: /* pos-z */ vec[0]= tvec[1]; @@ -1580,12 +1582,12 @@ void vec_apply_track(float vec[3], short axis) vec[2]= -tvec[2]; break; case 4: /* neg-y */ - vec[0]= -tvec[0]; + vec[0]= -tvec[2]; /* vec[1]= 0.0; */ - vec[2]= -tvec[2]; + vec[2]= tvec[0]; break; case 5: /* neg-z */ - vec[0]= tvec[0]; + vec[0]= -tvec[0]; vec[1]= -tvec[1]; /* vec[2]= 0.0; */ break; -- cgit v1.2.3 From c79e054538074d5149296994214397641124d76e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 8 Oct 2010 07:36:33 +0000 Subject: quat_apply_track had incomplete comments --- source/blender/blenlib/intern/math_rotation.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c index c4f12a5efc1..3b58fe88bf5 100644 --- a/source/blender/blenlib/intern/math_rotation.c +++ b/source/blender/blenlib/intern/math_rotation.c @@ -1539,21 +1539,24 @@ void quat_apply_track(float quat[4], short axis, short upflag) {0.70710676908493, 0.0, 0.0, 0.70710676908493}, /* pos-z90 */ {0.70710676908493, 0.0, 0.70710676908493, 0.0}, /* neg-y90 */ {0.5, -0.5, -0.5, 0.5}, /* Quaternion((1,0,0), radians(-90)) * Quaternion((0,1,0), radians(-90)) */ - {1, 0, 0, 0}};/* no rotation */ + {-3.0908619663705394e-08, 0.70710676908493, 0.70710676908493, 3.0908619663705394e-08}}; /* no rotation */ mul_qt_qtqt(quat, quat, quat_track[axis]); if(axis>2) axis= axis-3; - /* 90d rotation when the second */ - if(upflag != (2-axis)>>1) { // [0->1, 1->0, 2->0] - float q[4]= {0.70710676908493, 0, 0, 0}; + /* there are 2 possible up-axis for each axis used, the 'quat_track' applies so the first + * up axis is used X->Y, Y->X, Z->X, if this first up axis isn used then rotate 90d + * the strange bit shift below just find the low axis {X:Y, Y:X, Z:X} */ + if(upflag != (2-axis)>>1) { + float q[4]= {0.70710676908493, 0.0, 0.0, 0.0}; /* assign 90d rotation axis */ q[axis+1] = ((axis==1)) ? 0.70710676908493 : -0.70710676908493; /* flip non Y axis */ mul_qt_qtqt(quat, quat, q); } } + void vec_apply_track(float vec[3], short axis) { float tvec[3]; @@ -1572,14 +1575,14 @@ void vec_apply_track(float vec[3], short axis) /* vec[2]= tvec[2]; */ break; case 2: /* pos-z */ - vec[0]= tvec[1]; - vec[1]= -tvec[0]; + /* vec[0]= tvec[0]; */ + /* vec[1]= tvec[1]; */ // vec[2]= 0.0; */ break; case 3: /* neg-x */ /* vec[0]= 0.0; */ - vec[1]= -tvec[1]; - vec[2]= -tvec[2]; + vec[1]= tvec[2]; + vec[2]= -tvec[1]; break; case 4: /* neg-y */ vec[0]= -tvec[2]; -- cgit v1.2.3 From 30137cbdbc7babccdbb20f375fd73971d0d21f75 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 8 Oct 2010 11:33:10 +0000 Subject: bugfix [#24179] Button "Loop Cut and Slide" on Mesh Tools not work also added a message in the tooltip to say `why` a buttons disabled. depends on the operators poll setting the message. --- .../blender/editors/interface/interface_regions.c | 37 +++++++++++++++------- source/blender/editors/mesh/editmesh_mods.c | 2 +- source/blender/editors/mesh/loopcut.c | 2 +- source/blender/editors/screen/screen_ops.c | 6 +++- 4 files changed, 33 insertions(+), 14 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 53981f202ed..a0f852239c4 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "MEM_guardedalloc.h" @@ -300,7 +301,7 @@ typedef struct uiTooltipData { rcti bbox; uiFontStyle fstyle; char lines[MAX_TOOLTIP_LINES][512]; - int linedark[MAX_TOOLTIP_LINES]; + unsigned int color[MAX_TOOLTIP_LINES]; int totline; int toth, spaceh, lineh; } uiTooltipData; @@ -320,9 +321,7 @@ static void ui_tooltip_region_draw(const bContext *C, ARegion *ar) bbox.ymin= bbox.ymax - data->lineh; for(a=0; atotline; a++) { - if(!data->linedark[a]) glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - else glColor4f(0.5f, 0.5f, 0.5f, 1.0f); - + cpack(data->color[a]); uiStyleFontDraw(&data->fstyle, &bbox, data->lines[a]); bbox.ymin -= data->lineh + data->spaceh; bbox.ymax -= data->lineh + data->spaceh; @@ -358,6 +357,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) if(but->tip && strlen(but->tip)) { BLI_strncpy(data->lines[data->totline], but->tip, sizeof(data->lines[0])); + data->color[data->totline]= 0xFFFFFF; data->totline++; } @@ -367,7 +367,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) if(WM_key_event_operator_string(C, but->optype->idname, but->opcontext, prop, buf, sizeof(buf))) { BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), "Shortcut: %s", buf); - data->linedark[data->totline]= 1; + data->color[data->totline]= 0x888888; data->totline++; } } @@ -377,7 +377,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) ui_get_but_string(but, buf, sizeof(buf)); if(buf[0]) { BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), "Value: %s", buf); - data->linedark[data->totline]= 1; + data->color[data->totline]= 0x888888; data->totline++; } } @@ -388,7 +388,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) if (unit_type == PROP_UNIT_ROTATION) { if (RNA_property_type(but->rnaprop) == PROP_FLOAT) { BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), "Radians: %f", RNA_property_float_get_index(&but->rnapoin, but->rnaprop, but->rnaindex)); - data->linedark[data->totline]= 1; + data->color[data->totline]= 0x888888; data->totline++; } } @@ -397,21 +397,21 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) if(ui_but_anim_expression_get(but, buf, sizeof(buf))) { /* expression */ BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), "Expression: %s", buf); - data->linedark[data->totline]= 1; + data->color[data->totline]= 0x888888; data->totline++; } } /* rna info */ BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), "Python: %s.%s", RNA_struct_identifier(but->rnapoin.type), RNA_property_identifier(but->rnaprop)); - data->linedark[data->totline]= 1; + data->color[data->totline]= 0x888888; data->totline++; if(but->rnapoin.id.data) { ID *id= but->rnapoin.id.data; if(id->lib && id->lib->name) { BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), "Library: %s", id->lib->name); - data->linedark[data->totline]= 1; + data->color[data->totline]= 0x888888; data->totline++; } } @@ -425,12 +425,27 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) /* operator info */ BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), "Python: %s", str); - data->linedark[data->totline]= 1; + data->color[data->totline]= 0x888888; data->totline++; MEM_freeN(str); + + /* second check if we are disabled - why */ + if(but->flag & UI_BUT_DISABLED) { + const char *poll_msg; + CTX_wm_operator_poll_msg_set(C, NULL); + WM_operator_poll(C, but->optype); + poll_msg= CTX_wm_operator_poll_msg_get(C); + if(poll_msg) { + BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), "Disabled: %s", poll_msg); + data->color[data->totline]= 0x6666ff; /* alert */ + data->totline++; + } + } } + assert(data->totline < MAX_TOOLTIP_LINES); + if(data->totline == 0) { MEM_freeN(data); return NULL; diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c index f8018c686f5..164e8980b83 100644 --- a/source/blender/editors/mesh/editmesh_mods.c +++ b/source/blender/editors/mesh/editmesh_mods.c @@ -2113,7 +2113,7 @@ void MESH_OT_loop_select(wmOperatorType *ot) /* api callbacks */ ot->invoke= mesh_select_loop_invoke; - ot->poll= ED_operator_editmesh_region_view3d; + ot->poll= ED_operator_editmesh_view3d; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; diff --git a/source/blender/editors/mesh/loopcut.c b/source/blender/editors/mesh/loopcut.c index 7f1a7d0e1fc..13538a6f218 100644 --- a/source/blender/editors/mesh/loopcut.c +++ b/source/blender/editors/mesh/loopcut.c @@ -506,7 +506,7 @@ void MESH_OT_loopcut (wmOperatorType *ot) ot->invoke= ringcut_invoke; ot->modal= ringcut_modal; ot->cancel= ringcut_cancel; - ot->poll= ED_operator_editmesh_region_view3d; + ot->poll= ED_operator_editmesh_view3d; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 7b9bad5945d..613c8bc0178 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -244,7 +244,11 @@ int ED_operator_editmesh_view3d(bContext *C) int ED_operator_editmesh_region_view3d(bContext *C) { - return ED_operator_editmesh(C) && CTX_wm_region_view3d(C); + if(ED_operator_editmesh(C) && CTX_wm_region_view3d(C)) + return 1; + + CTX_wm_operator_poll_msg_set(C, "expected a view3d region & editmesh"); + return 0; } int ED_operator_editarmature(bContext *C) -- cgit v1.2.3 From 7006309b3a105dbab8d1d5534d95d53fab5174ef Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 8 Oct 2010 12:16:03 +0000 Subject: fix for console selection when pasting. --- source/blender/editors/space_console/console_ops.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source/blender') diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c index 3f04d0e4293..4e50b589bc6 100644 --- a/source/blender/editors/space_console/console_ops.c +++ b/source/blender/editors/space_console/console_ops.c @@ -782,6 +782,7 @@ void CONSOLE_OT_copy(wmOperatorType *ot) static int paste_exec(bContext *C, wmOperator *op) { + SpaceConsole *sc= CTX_wm_space_console(C); ConsoleLine *ci= console_history_verify(C); char *buf_str= WM_clipboard_text_get(0); @@ -805,7 +806,7 @@ static int paste_exec(bContext *C, wmOperator *op) ci= console_history_verify(C); } - console_line_insert(ci, buf_next); + console_select_offset(sc, console_line_insert(ci, buf_next)); } MEM_freeN(buf_str); -- cgit v1.2.3 From 48d2aac250624664cd1db77470af0fc45526f3c9 Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Fri, 8 Oct 2010 13:08:13 +0000 Subject: Fix for [#24092] F-Curve Cycle doesn't behave properly at end of Cycles (also: possible problem with how the cycle range is determined) * Cycle code had difficulties handling the transitions from one cycle iteration to the next one. * Now the transition frames are handled manually so that: - cycles before the actual fcurve data respect the first datapoint - cycles after the fcurve data respect the last datapoint * Also fixes a bug where the count of "before" cycles was off by one from the given value. --- source/blender/blenkernel/intern/fmodifier.c | 40 ++++++++++++++++++---------- 1 file changed, 26 insertions(+), 14 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c index f63b58fe489..5a10f93ac72 100644 --- a/source/blender/blenkernel/intern/fmodifier.c +++ b/source/blender/blenkernel/intern/fmodifier.c @@ -529,7 +529,7 @@ static float fcm_cycles_time (FCurve *fcu, FModifier *fcm, float cvalue, float e FMod_Cycles *data= (FMod_Cycles *)fcm->data; float prevkey[2], lastkey[2], cycyofs=0.0f; short side=0, mode=0; - int cycles=0; + int cycles=0, ofs=0; /* check if modifier is first in stack, otherwise disable ourself... */ // FIXME... @@ -571,6 +571,7 @@ static float fcm_cycles_time (FCurve *fcu, FModifier *fcm, float cvalue, float e side= -1; mode= data->before_mode; cycles= data->before_cycles; + ofs= prevkey[0]; } } else if (evaltime > lastkey[0]) { @@ -578,6 +579,7 @@ static float fcm_cycles_time (FCurve *fcu, FModifier *fcm, float cvalue, float e side= 1; mode= data->after_mode; cycles= data->after_cycles; + ofs= lastkey[0]; } } if ELEM(0, side, mode) @@ -585,11 +587,8 @@ static float fcm_cycles_time (FCurve *fcu, FModifier *fcm, float cvalue, float e /* find relative place within a cycle */ { - float cycdx=0, cycdy=0, ofs=0; - float cycle= 0; - - /* ofs is start frame of cycle */ - ofs= prevkey[0]; + float cycdx=0, cycdy=0; + float cycle= 0, cyct=0; /* calculate period and amplitude (total height) of a cycle */ cycdx= lastkey[0] - prevkey[0]; @@ -601,6 +600,9 @@ static float fcm_cycles_time (FCurve *fcu, FModifier *fcm, float cvalue, float e /* calculate the 'number' of the cycle */ cycle= ((float)side * (evaltime - ofs) / cycdx); + + /* calculate the time inside the cycle */ + cyct= fmod(evaltime - ofs, cycdx); /* check that cyclic is still enabled for the specified time */ if (cycles == 0) { @@ -608,7 +610,7 @@ static float fcm_cycles_time (FCurve *fcu, FModifier *fcm, float cvalue, float e * as this indicates infinite cycles... */ } - else if (cycle > (cycles+1)) { + else if (cycle > cycles) { /* we are too far away from range to evaluate * TODO: but we should still hold last value... */ @@ -617,26 +619,36 @@ static float fcm_cycles_time (FCurve *fcu, FModifier *fcm, float cvalue, float e /* check if 'cyclic extrapolation', and thus calculate y-offset for this cycle */ if (mode == FCM_EXTRAPOLATE_CYCLIC_OFFSET) { - cycyofs = (float)floor((evaltime - ofs) / cycdx); + if(side < 0) + cycyofs = (float)floor((evaltime - ofs) / cycdx); + else + cycyofs = (float)ceil((evaltime - ofs) / cycdx); cycyofs *= cycdy; } - + + /* special case for cycle start/end */ + if(cyct == 0.0f) { + evaltime = (side == 1 ? lastkey[0] : prevkey[0]); + + if((mode == FCM_EXTRAPOLATE_MIRROR) && ((int)cycle % 2)) + evaltime = (side == 1 ? prevkey[0] : lastkey[0]); + } /* calculate where in the cycle we are (overwrite evaltime to reflect this) */ - if ((mode == FCM_EXTRAPOLATE_MIRROR) && ((int)(cycle) % 2)) { + else if ((mode == FCM_EXTRAPOLATE_MIRROR) && ((int)(cycle+1) % 2)) { /* when 'mirror' option is used and cycle number is odd, this cycle is played in reverse * - for 'before' extrapolation, we need to flip in a different way, otherwise values past * then end of the curve get referenced (result of fmod will be negative, and with different phase) */ if (side < 0) - evaltime= (float)(prevkey[0] - fmod(evaltime-ofs, cycdx)); + evaltime= prevkey[0] - cyct; else - evaltime= (float)(lastkey[0] - fmod(evaltime-ofs, cycdx)); + evaltime= lastkey[0] - cyct; } else { /* the cycle is played normally... */ - evaltime= (float)(fmod(evaltime-ofs, cycdx) + ofs); + evaltime= prevkey[0] + cyct; } - if (evaltime < ofs) evaltime += cycdx; + if (evaltime < prevkey[0]) evaltime += cycdx; } /* store temp data if needed */ -- cgit v1.2.3 From 9bb10e571b99e4ddbfe11e52bdb385b0433e8b10 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 8 Oct 2010 22:33:43 +0000 Subject: bugfix [#23868] NodeGroup font resolution problem when editing it --- source/blender/editors/space_node/node_draw.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 0b33196c646..dfc63e032d9 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -1031,9 +1031,14 @@ static void node_draw_group(const bContext *C, ARegion *ar, SpaceNode *snode, bN else BLI_strncpy(showname, ngroup->id.name+2, sizeof(showname)); - // XXX this shows some scaling artifacts - UI_DrawString(rect.xmin+8.0f, rect.ymax+5.0f, showname); - + + uiDefBut(gnode->block, LABEL, 0, showname, (short)(rect.xmin+15), (short)(rect.ymax), + (int)(rect.xmax - rect.xmin-18.0f), NODE_DY, NULL, 0, 0, 0, 0, ""); + uiEndBlock(C, gnode->block); + uiDrawBlock(C, gnode->block); + gnode->block= NULL; + + /* links from groupsockets to the internal nodes */ node_draw_group_links(&ar->v2d, snode, gnode); @@ -1045,6 +1050,8 @@ static void node_draw_group(const bContext *C, ARegion *ar, SpaceNode *snode, bN if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) socket_circle_draw(sock, NODE_SOCKSIZE); + + /* and finally the whole tree */ node_draw_nodetree(C, ar, snode, ngroup); } -- cgit v1.2.3 From f72eef5de7fd109e9d71021adc0990b040b750b2 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Sat, 9 Oct 2010 21:17:14 +0000 Subject: COLLADA Import unit_settings to scene. Note: I use here RNA to do this, and I think I might slowly work on replacing low-level DNA usage with RNA where possible. --- source/blender/collada/DocumentImporter.cpp | 29 ++++++++++++++++++++++---- source/blender/collada/MeshImporter.cpp | 7 ++++--- source/blender/collada/MeshImporter.h | 4 +++- source/blender/collada/collada_internal.cpp | 32 ++++++++++++++++++++++++++--- source/blender/collada/collada_internal.h | 14 ++++++++++--- source/blender/makesrna/RNA_access.h | 4 ++++ 6 files changed, 76 insertions(+), 14 deletions(-) (limited to 'source/blender') diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp index 40e4d389b88..a406845c8a2 100644 --- a/source/blender/collada/DocumentImporter.cpp +++ b/source/blender/collada/DocumentImporter.cpp @@ -72,6 +72,8 @@ #include "DNA_camera_types.h" #include "DNA_lamp_types.h" +#include "RNA_access.h" + #include "MEM_guardedalloc.h" #include "DocumentImporter.h" @@ -130,7 +132,7 @@ public: /** Constructor. */ Writer(bContext *C, const char *filename) : mFilename(filename), mContext(C), armature_importer(&unit_converter, &mesh_importer, &anim_importer, CTX_data_scene(C)), - mesh_importer(&armature_importer, CTX_data_scene(C)), + mesh_importer(&unit_converter, &armature_importer, CTX_data_scene(C)), anim_importer(&unit_converter, &armature_importer, CTX_data_scene(C)) {} /** Destructor. */ @@ -172,8 +174,30 @@ public: { std::vector::iterator it; for (it = vscenes.begin(); it != vscenes.end(); it++) { + PointerRNA sceneptr, unit_settings; + PropertyRNA *system, *scale; // TODO: create a new scene except the selected - use current blender scene for it Scene *sce = CTX_data_scene(mContext); + + // for scene unit settings: system, scale_length + RNA_id_pointer_create(&sce->id, &sceneptr); + unit_settings = RNA_pointer_get(&sceneptr, "unit_settings"); + system = RNA_struct_find_property(&unit_settings, "system"); + scale = RNA_struct_find_property(&unit_settings, "scale_length"); + + switch(unit_converter.isMetricSystem()) { + case UnitConverter::Metric: + RNA_property_enum_set(&unit_settings, system, USER_UNIT_METRIC); + break; + case UnitConverter::Imperial: + RNA_property_enum_set(&unit_settings, system, USER_UNIT_IMPERIAL); + break; + default: + RNA_property_enum_set(&unit_settings, system, USER_UNIT_NONE); + break; + } + RNA_property_float_set(&unit_settings, scale, unit_converter.getLinearMeter()); + const COLLADAFW::NodePointerArray& roots = (*it)->getRootNodes(); for (unsigned int i = 0; i < roots.getCount(); i++) { @@ -253,9 +277,6 @@ public: @return The writer should return true, if writing succeeded, false otherwise.*/ virtual bool writeGlobalAsset ( const COLLADAFW::FileInfo* asset ) { - // XXX take up_axis, unit into account - // COLLADAFW::FileInfo::Unit unit = asset->getUnit(); - // COLLADAFW::FileInfo::UpAxisType upAxis = asset->getUpAxisType(); unit_converter.read_asset(asset); return true; diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp index df5136f1cb4..44ac310e353 100644 --- a/source/blender/collada/MeshImporter.cpp +++ b/source/blender/collada/MeshImporter.cpp @@ -323,8 +323,9 @@ void MeshImporter::read_vertices(COLLADAFW::Mesh *mesh, Mesh *me) MVert *mvert; int i; - for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) + for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) { get_vector(mvert->co, pos, i); + } } int MeshImporter::triangulate_poly(unsigned int *indices, int totvert, MVert *verts, std::vector& tri) @@ -631,7 +632,7 @@ void MeshImporter::read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris) } } - mat_prim_map[mp->getMaterialId()].push_back(prim); + mat_prim_map[mp->getMaterialId()].push_back(prim); } geom_uid_mat_mapping_map[mesh->getUniqueId()] = mat_prim_map; @@ -689,7 +690,7 @@ bool MeshImporter::flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& nor, return true; } -MeshImporter::MeshImporter(ArmatureImporter *arm, Scene *sce) : scene(sce), armature_importer(arm) {} +MeshImporter::MeshImporter(UnitConverter *unitconv, ArmatureImporter *arm, Scene *sce) : unitconverter(unitconv), scene(sce), armature_importer(arm) {} Object *MeshImporter::get_object_by_geom_uid(const COLLADAFW::UniqueId& geom_uid) { diff --git a/source/blender/collada/MeshImporter.h b/source/blender/collada/MeshImporter.h index 1fa9ebfbabc..055c4798855 100644 --- a/source/blender/collada/MeshImporter.h +++ b/source/blender/collada/MeshImporter.h @@ -119,10 +119,12 @@ private: void get_vector(float v[3], COLLADAFW::MeshVertexData& arr, int i); bool flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& nor, int count); + + UnitConverter *unitconverter; public: - MeshImporter(ArmatureImporter *arm, Scene *sce); + MeshImporter(UnitConverter *unitconv, ArmatureImporter *arm, Scene *sce); virtual Object *get_object_by_geom_uid(const COLLADAFW::UniqueId& geom_uid); diff --git a/source/blender/collada/collada_internal.cpp b/source/blender/collada/collada_internal.cpp index 67ee4818f7e..6f401c1856f 100644 --- a/source/blender/collada/collada_internal.cpp +++ b/source/blender/collada/collada_internal.cpp @@ -28,12 +28,38 @@ UnitConverter::UnitConverter() : unit(), up_axis(COLLADAFW::FileInfo::Z_UP) {} void UnitConverter::read_asset(const COLLADAFW::FileInfo* asset) { + unit = asset->getUnit(); + up_axis = asset->getUpAxisType(); } -// TODO -// convert vector vec from COLLADA format to Blender -void UnitConverter::convertVec3(float *vec) +UnitConverter::UnitSystem UnitConverter::isMetricSystem() { + switch(unit.getLinearUnitUnit()) { + case COLLADAFW::FileInfo::Unit::MILLIMETER: + case COLLADAFW::FileInfo::Unit::CENTIMETER: + case COLLADAFW::FileInfo::Unit::DECIMETER: + case COLLADAFW::FileInfo::Unit::METER: + case COLLADAFW::FileInfo::Unit::KILOMETER: + return UnitConverter::Metric; + case COLLADAFW::FileInfo::Unit::INCH: + case COLLADAFW::FileInfo::Unit::FOOT: + case COLLADAFW::FileInfo::Unit::YARD: + return UnitConverter::Imperial; + default: + return UnitConverter::None; + } +} + +float UnitConverter::getLinearMeter() +{ + return (float)unit.getLinearUnitMeter(); +} + +void UnitConverter::convertVector3(COLLADABU::Math::Vector3 &vec, float *v) +{ + v[0] = vec.x; + v[1] = vec.y; + v[2] = vec.z; } // TODO need also for angle conversion, time conversion... diff --git a/source/blender/collada/collada_internal.h b/source/blender/collada/collada_internal.h index 1e3546263da..72b03a3d090 100644 --- a/source/blender/collada/collada_internal.h +++ b/source/blender/collada/collada_internal.h @@ -43,14 +43,22 @@ private: public: + enum UnitSystem { + None, + Metric, + Imperial + }; + // Initialize with Z_UP, since Blender uses right-handed, z-up UnitConverter(); void read_asset(const COLLADAFW::FileInfo* asset); - // TODO - // convert vector vec from COLLADA format to Blender - void convertVec3(float *vec); + void convertVector3(COLLADABU::Math::Vector3 &vec, float *v); + + UnitConverter::UnitSystem isMetricSystem(void); + + float getLinearMeter(void); // TODO need also for angle conversion, time conversion... diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index e454dda0ae6..ab1319653b8 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -834,7 +834,11 @@ char *RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, in int RNA_string_length(PointerRNA *ptr, const char *name); void RNA_string_set(PointerRNA *ptr, const char *name, const char *value); +/** + * Retrieve the named property from PointerRNA. + */ PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name); +/* Set the property name of PointerRNA ptr to ptr_value */ void RNA_pointer_set(PointerRNA *ptr, const char *name, PointerRNA ptr_value); void RNA_pointer_add(PointerRNA *ptr, const char *name); -- cgit v1.2.3 From d420d09da982e1a874ffe2b0612b8fdd0afc980e Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Sat, 9 Oct 2010 21:31:32 +0000 Subject: Fix compiling for MingW too. --- source/blender/collada/MeshImporter.cpp | 2 +- source/blender/collada/SkinInfo.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender') diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp index 44ac310e353..be7abc3ec4e 100644 --- a/source/blender/collada/MeshImporter.cpp +++ b/source/blender/collada/MeshImporter.cpp @@ -24,7 +24,7 @@ #include -#ifndef WIN32 +#if !defined(WIN32) || defined(FREE_WINDOWS) #include #endif diff --git a/source/blender/collada/SkinInfo.cpp b/source/blender/collada/SkinInfo.cpp index a3ac6a30c59..ba9451ecf84 100644 --- a/source/blender/collada/SkinInfo.cpp +++ b/source/blender/collada/SkinInfo.cpp @@ -24,7 +24,7 @@ #include -#ifndef WIN32 +#if !defined(WIN32) || defined(FREE_WINDOWS) #include #endif -- cgit v1.2.3