[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