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. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to