[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [21402] branches/soc-2009-kazanbas: Integrated unit testing framework with scons on Linux.
Arystanbek Dyussenov
arystan.d at gmail.com
Tue Jul 7 10:38:18 CEST 2009
Revision: 21402
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=21402
Author: kazanbas
Date: 2009-07-07 10:38:18 +0200 (Tue, 07 Jul 2009)
Log Message:
-----------
Integrated unit testing framework with scons on Linux.
I needed this to make sure that BKE_copy_images works properly,
probably will be useful in future.
Using Check framework (http://check.sourceforge.net/doc/check.html/index.html).
WITH_BF_UNIT_TEST option builds 'alltest' program under [BUILDDIR]/bin,
which, when executed, runs unit tests, currently only 1.
Example output:
----------------------------------------------------------------------
Running suite(s): Image
0%: Checks: 1, Failures: 1, Errors: 0
tests/alltest.c:74:F:Core:test_copy_images:0: Expected //bar/image.png to be translated to /tmp/bar/image.png, got /tmp/bar/image.pn.
----------------------------------------------------------------------
Spent lots of time (a couple of days actually :) to figure out how to
link the test program with Blender libraries. As it turned out there
are circular dependencies among Blender libraries. GCC by default
doesn't expect circular dependencies - dependant libs should precede
libs they depend on.
The magical --start-group linker option helped to solve this
(http://stephane.carrez.free.fr/doc/ld_2.html#IDX122).
Also:
- added bpy.util module. bpy.sys.* functions will move here later
- added bpy.util.copy_images that uses BKE_copy_images
- export_obj.py uses bpy.util.copy_images
Modified Paths:
--------------
branches/soc-2009-kazanbas/SConstruct
branches/soc-2009-kazanbas/release/io/export_obj.py
branches/soc-2009-kazanbas/source/blender/blenkernel/BKE_image.h
branches/soc-2009-kazanbas/source/blender/blenkernel/SConscript
branches/soc-2009-kazanbas/source/blender/blenkernel/intern/image.c
branches/soc-2009-kazanbas/source/blender/python/intern/bpy_interface.c
branches/soc-2009-kazanbas/source/blender/python/intern/bpy_util.c
branches/soc-2009-kazanbas/source/blender/python/intern/bpy_util.h
branches/soc-2009-kazanbas/tools/btools.py
Modified: branches/soc-2009-kazanbas/SConstruct
===================================================================
--- branches/soc-2009-kazanbas/SConstruct 2009-07-07 07:29:21 UTC (rev 21401)
+++ branches/soc-2009-kazanbas/SConstruct 2009-07-07 08:38:18 UTC (rev 21402)
@@ -407,7 +407,16 @@
if 'blender' in B.targets or not env['WITH_BF_NOBLENDER']:
#env.BlenderProg(B.root_build_dir, "blender", dobj , [], mainlist + thestatlibs + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blender')
- env.BlenderProg(B.root_build_dir, "blender", dobj + mainlist, [], thestatlibs + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blender')
+ blen = env.BlenderProg(B.root_build_dir, "blender", dobj + mainlist, [], thestatlibs + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blender')
+
+ build_data = {"lib": thestatlibs + thesyslibs, "libpath": thelibincs, "blen": blen}
+
+ Export('env')
+ Export('build_data')
+
+ BuildDir(B.root_build_dir+'/tests', 'tests', duplicate=0)
+ SConscript(B.root_build_dir+'/tests/SConscript')
+
if env['WITH_BF_PLAYER']:
playerlist = B.create_blender_liblist(env, 'player')
env.BlenderProg(B.root_build_dir, "blenderplayer", dobj + playerlist, [], thestatlibs + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blenderplayer')
Modified: branches/soc-2009-kazanbas/release/io/export_obj.py
===================================================================
--- branches/soc-2009-kazanbas/release/io/export_obj.py 2009-07-07 07:29:21 UTC (rev 21401)
+++ branches/soc-2009-kazanbas/release/io/export_obj.py 2009-07-07 08:38:18 UTC (rev 21402)
@@ -178,19 +178,22 @@
pass
# Now copy images
- copyCount = 0
+# copyCount = 0
- for bImage in uniqueImages.values():
- image_path = bpy.sys.expandpath(bImage.filename)
- if bpy.sys.exists(image_path):
- # Make a name for the target path.
- dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1]
- if not bpy.sys.exists(dest_image_path): # Image isnt alredy there
- print('\tCopying "%s" > "%s"' % (image_path, dest_image_path))
- copy_file(image_path, dest_image_path)
- copyCount+=1
+# for bImage in uniqueImages.values():
+# image_path = bpy.sys.expandpath(bImage.filename)
+# if bpy.sys.exists(image_path):
+# # Make a name for the target path.
+# dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1]
+# if not bpy.sys.exists(dest_image_path): # Image isnt alredy there
+# print('\tCopying "%s" > "%s"' % (image_path, dest_image_path))
+# copy_file(image_path, dest_image_path)
+# copyCount+=1
+ paths= bpy.util.copy_images(uniqueImages.values(), dest_dir)
+
print('\tCopied %d images' % copyCount)
+# print('\tCopied %d images' % copyCount)
# XXX not converted
def test_nurbs_compat(ob):
Modified: branches/soc-2009-kazanbas/source/blender/blenkernel/BKE_image.h
===================================================================
--- branches/soc-2009-kazanbas/source/blender/blenkernel/BKE_image.h 2009-07-07 07:29:21 UTC (rev 21401)
+++ branches/soc-2009-kazanbas/source/blender/blenkernel/BKE_image.h 2009-07-07 08:38:18 UTC (rev 21402)
@@ -40,6 +40,7 @@
struct Tex;
struct anim;
struct Scene;
+struct ListBase;
/* call from library */
void free_image(struct Image *me);
@@ -154,6 +155,11 @@
/* merge source into dest, and free source */
void BKE_image_merge(struct Image *dest, struct Image *source);
+/* ********************************** FOR EXPORTERS *********************** */
+
+/* copy images into dest_dir */
+void BKE_copy_images(struct ListBase *images, char *dest_dir, struct ListBase *filenames);
+
#ifdef __cplusplus
}
#endif
Modified: branches/soc-2009-kazanbas/source/blender/blenkernel/SConscript
===================================================================
--- branches/soc-2009-kazanbas/source/blender/blenkernel/SConscript 2009-07-07 07:29:21 UTC (rev 21401)
+++ branches/soc-2009-kazanbas/source/blender/blenkernel/SConscript 2009-07-07 08:38:18 UTC (rev 21402)
@@ -57,6 +57,9 @@
if env['WITH_BF_LCMS']:
defs.append('WITH_LCMS')
+
+if env['WITH_BF_UNIT_TEST']:
+ defs.append('WITH_UNIT_TEST')
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
incs += ' ' + env['BF_PTHREADS_INC']
Modified: branches/soc-2009-kazanbas/source/blender/blenkernel/intern/image.c
===================================================================
--- branches/soc-2009-kazanbas/source/blender/blenkernel/intern/image.c 2009-07-07 07:29:21 UTC (rev 21401)
+++ branches/soc-2009-kazanbas/source/blender/blenkernel/intern/image.c 2009-07-07 08:38:18 UTC (rev 21402)
@@ -2109,3 +2109,120 @@
}
}
+/*
+ Copy list of images to dest_dir.
+
+ paths is optional, if given, image paths for each image will be written in it.
+ If an image file doesn't exist, NULL is added in paths.
+
+ Logic:
+
+ For each image if it's "below" current .blend file directory,
+ rebuild the same dir structure in dest_dir.
+
+ For example //textures/foo/bar.png becomes
+ [dest_dir]/textures/foo/bar.png.
+
+ If an image is not "below" current .blend file directory, disregard
+ it's path and copy it in the same directory where 3D file goes.
+
+ For example //../foo/bar.png becomes [dest_dir]/bar.png.
+
+ This logic will help ensure that all image paths are relative and
+ that a user gets his images in one place. It'll also provide
+ consistent behaviour across exporters.
+*/
+void BKE_copy_images(ListBase *images, char *dest_dir, ListBase *paths)
+{
+ char path[FILE_MAX];
+ char dir[FILE_MAX];
+ char base[FILE_MAX];
+ char blend_dir[FILE_MAX]; /* directory, where current .blend file resides */
+ char dest_path[FILE_MAX];
+ int len;
+ Image *im;
+ LinkData *link;
+
+ if (paths) {
+ memset(paths, 0, sizeof(*paths));
+ }
+
+ BLI_split_dirfile_basic(G.sce, blend_dir, NULL);
+
+ link= images->first;
+
+ while (link) {
+ im= link->data;
+
+ BLI_strncpy(path, im->name, sizeof(path));
+
+ /* expand "//" in filename and get absolute path */
+ BLI_convertstringcode(path, G.sce);
+
+ /* in unit tests, we don't want to modify the filesystem */
+#ifndef WITH_UNIT_TEST
+ /* proceed only if image file exists */
+ if (!BLI_exists(path)) {
+
+ if (paths) {
+ LinkData *ld = MEM_callocN(sizeof(LinkData), "PathLinkData");
+ ld->data= NULL;
+ BLI_addtail(paths, ld);
+ }
+
+ continue;
+ }
+#endif
+
+ /* get the directory part */
+ BLI_split_dirfile_basic(path, dir, base);
+
+ len= strlen(blend_dir);
+
+ /* if image is "below" current .blend file directory */
+ if (!strncmp(path, blend_dir, len)) {
+
+ /* if image is _in_ current .blend file directory */
+ if (!strcmp(dir, blend_dir)) {
+ /* copy to dest_dir */
+ BLI_join_dirfile(dest_path, dest_dir, base);
+ }
+ /* "below" */
+ else {
+ char rel[FILE_MAX];
+
+ /* rel = image_path_dir - blend_dir */
+ BLI_strncpy(rel, dir + len, sizeof(rel));
+
+ BLI_join_dirfile(dest_path, dest_dir, rel);
+
+#ifndef WITH_UNIT_TEST
+ /* build identical directory structure under dest_dir */
+ BLI_make_existing_file(dest_path);
+#endif
+
+ BLI_join_dirfile(dest_path, dest_path, base);
+ }
+
+ }
+ /* image is out of current directory */
+ else {
+ /* copy to dest_dir */
+ BLI_join_dirfile(dest_path, dest_dir, base);
+ }
+
+#ifndef WITH_UNIT_TEST
+ BLI_copy_fileops(path, dest_path);
+#endif
+
+ if (paths) {
+ LinkData *ld = MEM_callocN(sizeof(LinkData), "PathLinkData");
+ len= strlen(dest_path) + 1;
+ ld->data= MEM_callocN(len, "PathLinkData");
+ BLI_strncpy(ld->data, dest_path, len);
+ BLI_addtail(paths, ld);
+ }
+
+ link= link->next;
+ }
+}
Modified: branches/soc-2009-kazanbas/source/blender/python/intern/bpy_interface.c
===================================================================
--- branches/soc-2009-kazanbas/source/blender/python/intern/bpy_interface.c 2009-07-07 07:29:21 UTC (rev 21401)
+++ branches/soc-2009-kazanbas/source/blender/python/intern/bpy_interface.c 2009-07-07 08:38:18 UTC (rev 21402)
@@ -92,6 +92,9 @@
PyObject *mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0);
PyModule_AddObject( mod, "data", BPY_rna_module() );
PyModule_AddObject( mod, "types", BPY_rna_types() );
+ PyModule_AddObject( mod, "util", BPY_util_module() );
+
+ /* XXX this will move to bpy.util */
PyModule_AddObject( mod, "sys", BPY_sys_module() );
}
Modified: branches/soc-2009-kazanbas/source/blender/python/intern/bpy_util.c
===================================================================
--- branches/soc-2009-kazanbas/source/blender/python/intern/bpy_util.c 2009-07-07 07:29:21 UTC (rev 21401)
+++ branches/soc-2009-kazanbas/source/blender/python/intern/bpy_util.c 2009-07-07 08:38:18 UTC (rev 21402)
@@ -25,12 +25,17 @@
#include "DNA_listBase.h"
#include "RNA_access.h"
#include "bpy_util.h"
-#include "BLI_dynstr.h"
+#include "bpy_rna.h"
+
#include "MEM_guardedalloc.h"
-#include "BKE_report.h"
+#include "BLI_dynstr.h"
+#include "BLI_listbase.h"
+#include "BKE_report.h"
+#include "BKE_image.h"
#include "BKE_context.h"
+
bContext* __py_context = NULL;
bContext* BPy_GetContext(void) { return __py_context; };
void BPy_SetContext(bContext *C) { __py_context= C; };
@@ -464,3 +469,127 @@
Py_DECREF(pystring);
return 1;
}
+
+
+/* bpy.util module */
+static PyObject *bpy_util_copy_images(PyObject *self, PyObject *args);
+
+struct PyMethodDef bpy_util_methods[] = {
+ {"copy_images", bpy_util_copy_images, METH_VARARGS, NULL},
+ {NULL, NULL, 0, NULL}
+};
+
+#if PY_VERSION_HEX >= 0x03000000
+static struct PyModuleDef bpy_util_module = {
+ PyModuleDef_HEAD_INIT,
+ "bpyutil",
+ NULL,
+ -1,
+ bpy_util_methods,
+ NULL, NULL, NULL, NULL
+};
+#endif
+
+PyObject *BPY_util_module( void )
+{
+ PyObject *submodule, *dict;
+
+#if PY_VERSION_HEX >= 0x03000000
+ submodule= PyModule_Create(&bpy_util_module);
+#else /* Py2.x */
+ submodule= Py_InitModule3("bpyutil", bpy_util_methods, NULL);
+#endif
+
+ dict = PyModule_GetDict(submodule);
+
+ return submodule;
+}
+
+/*
+ copy_images(images, dest_dir)
+ return filenames
+*/
+static PyObject *bpy_util_copy_images(PyObject *self, PyObject *args)
+{
+ const char *dest_dir;
+ ListBase *images;
+ ListBase *paths;
+ LinkData *link;
+ PyObject *seq;
+ PyObject *ret;
+ PyObject *item;
+ int i;
+ int len;
+
+ /* check args/types */
+ if (!PyArg_ParseTuple(args, "Os", &seq, &dest_dir)) {
+ PyErr_SetString(PyExc_TypeError, "Invalid arguments.");
+ return NULL;
+ }
+
+ /* expecting a sequence of Image objects */
+ if (!PySequence_Check(seq)) {
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list