API:
authorArystanbek Dyussenov <arystan.d@gmail.com>
Thu, 23 Jul 2009 12:55:26 +0000 (12:55 +0000)
committerArystanbek Dyussenov <arystan.d@gmail.com>
Thu, 23 Jul 2009 12:55:26 +0000 (12:55 +0000)
- replaced BKE_copy_images with BKE_export_image, now it handles only one image at a time, this is better since for exporters it is
easier to export one image at a time writing new image path to a file
- exposing BKE_export_image in RNA as Image.export, interestingly, RNA allowed me to define a function with PROP_STRING return type
although it doesn't free memory, will fix that in the next commit
- removed bpy.util.copy_images

Unit tests:
- re-wrote a test for BKE_export_image, it's more compact now
- moved unit tests to the creator module to avoid another executable, now running tests with `blender --test`
- as before, unit tests are built only if WITH_BF_UNIT_TEST is non 0

13 files changed:
SConstruct
release/io/export_fbx.py
source/blender/blenkernel/BKE_image.h
source/blender/blenkernel/intern/image.c
source/blender/makesrna/intern/makesrna.c
source/blender/makesrna/intern/rna_image.c
source/blender/python/intern/bpy_interface.c
source/blender/python/intern/bpy_util.c
source/creator/SConscript
source/creator/creator.c
source/creator/tests/alltest.c [new file with mode: 0644]
tools/Blender.py
tools/btools.py

index 2d1daba..c1b4f8d 100644 (file)
@@ -409,14 +409,6 @@ 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')
        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')
index a861436..f98cefb 100644 (file)
@@ -356,7 +356,7 @@ def write(filename, batch_objects = None, \
                EXP_OBS_SELECTED =                      True,
                EXP_MESH =                                      True,
                EXP_MESH_APPLY_MOD =            True,
-               EXP_MESH_HQ_NORMALS =           False,
+#              EXP_MESH_HQ_NORMALS =           False,
                EXP_ARMATURE =                          True,
                EXP_LAMP =                                      True,
                EXP_CAMERA =                            True,
@@ -464,7 +464,7 @@ def write(filename, batch_objects = None, \
                                False,
                                EXP_MESH,
                                EXP_MESH_APPLY_MOD,
-                               EXP_MESH_HQ_NORMALS,
+#                              EXP_MESH_HQ_NORMALS,
                                EXP_ARMATURE,
                                EXP_LAMP,
                                EXP_CAMERA,
@@ -2306,19 +2306,25 @@ def write(filename, batch_objects = None, \
        
        # Build blenObject -> fbxObject mapping
        # this is needed for groups as well as fbxParenting
-       for ob in bpy.data.objects:     ob.tag = False
+#      for ob in bpy.data.objects:     ob.tag = False
 #      bpy.data.objects.tag = False
+
+       # using a list of object names for tagging (Arystan)
+       tagged_objects = []
+
        tmp_obmapping = {}
        for ob_generic in ob_all_typegroups:
                for ob_base in ob_generic:
-                       ob_base.blenObject.tag = True
+                       tagged_objects.append(ob_base.blenObject.name)
+#                      ob_base.blenObject.tag = True
                        tmp_obmapping[ob_base.blenObject] = ob_base
        
        # Build Groups from objects we export
        for blenGroup in bpy.data.groups:
                fbxGroupName = None
                for ob in blenGroup.objects:
-                       if ob.tag:
+                       if ob.name in tagged_objects:
+#                      if ob.tag:
                                if fbxGroupName == None:
                                        fbxGroupName = sane_groupname(blenGroup)
                                        groups.append((fbxGroupName, blenGroup))
@@ -2331,7 +2337,8 @@ def write(filename, batch_objects = None, \
        for ob_generic in ob_all_typegroups:
                for my_ob in ob_generic:
                        parent = my_ob.blenObject.parent
-                       if parent and parent.tag: # does it exist and is it in the mapping
+                       if parent and parent.name in tagged_objects: # does it exist and is it in the mapping
+#                      if parent and parent.tag: # does it exist and is it in the mapping
                                my_ob.fbxParent = tmp_obmapping[parent]
        
        
@@ -2734,9 +2741,11 @@ Connections:  {''')
                tmp_actions = [None] # None is the default action
                blenActionDefault = None
                action_lastcompat = None
+
+               # instead of tagging
+               tagged_actions = []
                
                if ANIM_ACTION_ALL:
-                       for a in bpy.data.actions: a.tag = False
 #                      bpy.data.actions.tag = False
                        tmp_actions = list(bpy.data.actions)
                        
@@ -2759,7 +2768,8 @@ Connections:  {''')
                                        
                                        if action_chan_names: # at least one channel matches.
                                                my_arm.blenActionList.append(action)
-                                               action.tag = True
+                                               tagged_actions.append(action.name)
+#                                              action.tag = True
                                                tmp_act_count += 1
                                                
                                                # incase there is no actions applied to armatures
@@ -2786,7 +2796,8 @@ Takes:  {''')
                for blenAction in tmp_actions:
                        # we have tagged all actious that are used be selected armatures
                        if blenAction:
-                               if blenAction.tag:
+                               if blenAction.name in tagged_actions:
+#                              if blenAction.tag:
                                        print('\taction: "%s" exporting...' % blenAction.name)
                                else:
                                        print('\taction: "%s" has no armature using it, skipping' % blenAction.name)
@@ -3065,7 +3076,7 @@ Takes:  {''')
        # copy images if enabled
        if EXP_IMAGE_COPY:
 #              copy_images( basepath,  [ tex[1] for tex in textures if tex[1] != None ])
-               bpy.util.copy_images( basepath,  [ tex[1] for tex in textures if tex[1] != None ])      
+               bpy.util.copy_images( [ tex[1] for tex in textures if tex[1] != None ], basepath)       
        
        print('export finished in %.4f sec.' % (bpy.sys.time() - start_time))
 #      print 'export finished in %.4f sec.' % (Blender.sys.time() - start_time)
@@ -3393,7 +3404,7 @@ class EXPORT_OT_fbx(bpy.types.Operator):
                bpy.props.BoolProperty(attr="ANIM_OPTIMIZE", name="Optimize Keyframes", description="Remove double keyframes", default=True),
                bpy.props.FloatProperty(attr="ANIM_OPTIMIZE_PRECISSION", name="Precision", description="Tolerence for comparing double keyframes (higher for greater accuracy)", min=1, max=16, soft_min=1, soft_max=16, default=6.0),
 #              bpy.props.BoolProperty(attr="ANIM_ACTION_ALL", name="Current Action", description="Use actions currently applied to the armatures (use scene start/end frame)", default=True),
-               bpy.props.BoolProperty(attr="ANIM_ACTION_ALL", name="All Actions", description="Use all actions for armatures", default=False),
+               bpy.props.BoolProperty(attr="ANIM_ACTION_ALL", name="All Actions", description="Use all actions for armatures, if false, use current action", default=False),
                # batch
                bpy.props.BoolProperty(attr="BATCH_ENABLE", name="Enable Batch", description="Automate exporting multiple scenes or groups to files", default=False),
                bpy.props.BoolProperty(attr="BATCH_GROUP", name="Group > File", description="Export each group as an FBX file, if false, export each scene as an FBX file", default=False),
@@ -3421,7 +3432,7 @@ class EXPORT_OT_fbx(bpy.types.Operator):
                          self.EXP_OBS_SELECTED,
                          self.EXP_MESH,
                          self.EXP_MESH_APPLY_MOD,
-                         self.EXP_MESH_HQ_NORMALS,
+#                        self.EXP_MESH_HQ_NORMALS,
                          self.EXP_ARMATURE,
                          self.EXP_LAMP,
                          self.EXP_CAMERA,
index f3f5266..052f773 100644 (file)
@@ -155,10 +155,9 @@ struct Image *BKE_image_copy(struct Image *ima);
 /* merge source into dest, and free source */
 void BKE_image_merge(struct Image *dest, struct Image *source);
 
-/* ********************************** FOR EXPORTERS *********************** */
+/* copy image file to a directory rebuilding subdirectory structure */
+int BKE_export_image(struct Image *im, const char *dest_dir, char *out_path, int out_path_len);
 
-/* copy images into dest_dir */
-void BKE_copy_images(struct ListBase *images, char *dest_dir, struct ListBase *filenames);
 
 #ifdef __cplusplus
 }
index 833d5ac..a469752 100644 (file)
@@ -2117,30 +2117,27 @@ void BKE_image_user_calc_imanr(ImageUser *iuser, int cfra, int fieldnr)
 }
 
 /*
-  Copy list of images to dest_dir.
-
-  paths is optional, if given, image paths for each image will be written in it.
-  It will also contain NULLs for images that cannot be copied.
-  If an image file doesn't exist, NULL is added in paths.
+  Copy an image to destination directory rebuilding subdirectory structure if needed.
+  Target image path is written to out_path.
+  Returns 1 on success, 0 otherwise.
 
   Logic:
 
-  For each image if it's "below" current .blend file directory,
-  rebuild the same dir structure in dest_dir.
+  - if an image is "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.
+  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.
+  - 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)
+
+ */
+int BKE_export_image(Image *im, const char *dest_dir, char *out_path, int out_path_len)
 {
        char path[FILE_MAX];
        char dir[FILE_MAX];
@@ -2148,88 +2145,77 @@ void BKE_copy_images(ListBase *images, char *dest_dir, ListBase *paths)
        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));
-       }
+       out_path[0]= 0;
 
        BLI_split_dirfile_basic(G.sce, blend_dir, NULL);
-       
-       link= images->first;
-
-       while (link) {
-               im= link->data;
-
-               LinkData *ld = MEM_callocN(sizeof(LinkData), "PathLinkData");
-               ld->data= NULL;
-               BLI_addtail(paths, ld);
 
-               if (!strcmp(im->name, "") || im->type != IMA_TYPE_IMAGE)
-                       goto next;
+       if (!strcmp(im->name, "") || im->type != IMA_TYPE_IMAGE) {
+               if (G.f & G_DEBUG) printf("invalid image type\n");
+               return 0;
+       }
 
-               BLI_strncpy(path, im->name, sizeof(path));
+       BLI_strncpy(path, im->name, sizeof(path));
 
-               /* expand "//" in filename and get absolute path */
-               BLI_convertstringcode(path, G.sce);
+       /* expand "//" in filename and get absolute path */
+       BLI_convertstringcode(path, G.sce);
 
-               /* in unit tests, we don't want to modify the filesystem */
+       /* 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))
-                       goto next;
+       /* proceed only if image file exists */
+       if (!BLI_exists(path)) {
+               if (G.f & G_DEBUG) printf("%s doesn't exist\n", path);
+               goto next;
+       }
 #endif
 
-               /* get the directory part */
-               BLI_split_dirfile_basic(path, dir, base);
+       /* get the directory part */
+       BLI_split_dirfile_basic(path, dir, base);
 
-               len= strlen(blend_dir);
+       len= strlen(blend_dir);
 
-               /* if image is "below" current .blend file directory */
-               if (!strncmp(path, blend_dir, len)) {
+       /* 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];
+               /* 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));
+                       /* rel = image_path_dir - blend_dir */
+                       BLI_strncpy(rel, dir + len, sizeof(rel));
                                
-                               BLI_join_dirfile(dest_path, dest_dir, 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);
+                       /* 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);
+                       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
-               if (BLI_copy_fileops(path, dest_path) != 0)
-                       goto next;
+       if (G.f & G_DEBUG) printf("copying %s to %s\n", path, dest_path);
+
+       if (BLI_copy_fileops(path, dest_path) != 0) {
+               if (G.f & G_DEBUG) printf("couldn't copy %s to %s\n", path, dest_path);
+               return 0;
+       }
 #endif
 
-               if (paths) {
-                       len= strlen(dest_path) + 1;
-                       ld->data= MEM_callocN(len, "PathLinkData");
-                       BLI_strncpy(ld->data, dest_path, len);
-               }
+       BLI_strncpy(out_path, dest_path, out_path_len);
 
-       next:
-               link= link->next;
-       }
+       return 1;
 }
index 63ce578..03d8edd 100644 (file)
@@ -1936,7 +1936,7 @@ RNAProcessItem PROCESS_ITEMS[]= {
        {"rna_fcurve.c", NULL, RNA_def_fcurve},
        {"rna_fluidsim.c", NULL, RNA_def_fluidsim},
        {"rna_group.c", NULL, RNA_def_group},
-       {"rna_image.c", NULL, RNA_def_image},
+       {"rna_image.c", "rna_image_api.c", RNA_def_image},
        {"rna_key.c", NULL, RNA_def_key},
        {"rna_lamp.c", NULL, RNA_def_lamp},
        {"rna_lattice.c", NULL, RNA_def_lattice},
index fbef838..5366296 100644 (file)
@@ -312,6 +312,8 @@ static void rna_def_image(BlenderRNA *brna)
        RNA_def_property_int_funcs(prop, "rna_Image_depth_get", NULL, NULL);
        RNA_def_property_ui_text(prop, "Depth", "Image bit depth.");
        RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+       RNA_api_image(srna);
 }
 
 void RNA_def_image(BlenderRNA *brna)
index f045e97..4ab79dc 100644 (file)
@@ -93,7 +93,7 @@ void BPY_update_modules( void )
        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() );
+       /* PyModule_AddObject( mod, "util", BPY_util_module() ); */
 
        /* XXX this will move to bpy.util */
        PyModule_AddObject( mod, "sys", BPY_sys_module() );
index dc31328..89a68ba 100644 (file)
@@ -488,126 +488,3 @@ int BPy_errors_to_report(ReportList *reports)
        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)) {
-               PyErr_SetString(PyExc_TypeError, "Expected a sequence of images.");
-               return NULL;
-       }
-
-       /* create image list */
-       len= PySequence_Size(seq);
-
-       if (!len) {
-               PyErr_SetString(PyExc_TypeError, "At least one image should be specified.");
-               return NULL;
-       }
-
-       /* make sure all sequence items are Image */
-       for(i= 0; i < len; i++) {
-               item= PySequence_GetItem(seq, i);
-
-               if (!BPy_StructRNA_Check(item) || ((BPy_StructRNA*)item)->ptr.type != &RNA_Image) {
-                       PyErr_SetString(PyExc_TypeError, "Expected a sequence of Image objects.");
-                       return NULL;
-               }
-       }
-
-       images= MEM_callocN(sizeof(*images), "ListBase of images");
-
-       for(i= 0; i < len; i++) {
-               BPy_StructRNA* srna;
-
-               item= PySequence_GetItem(seq, i);
-               srna= (BPy_StructRNA*)item;
-
-               link= MEM_callocN(sizeof(LinkData), "LinkData image");
-               link->data= srna->ptr.data;
-               BLI_addtail(images, link);
-
-               Py_DECREF(item);
-       }
-
-       paths= MEM_callocN(sizeof(*paths), "ListBase of image paths");
-
-       /* call BKE_copy_images */
-       BKE_copy_images(images, dest_dir, paths);
-
-       /* convert filenames */
-       ret= PyList_New(0);
-
-       for(link= paths->first; link; link= link->next) {
-               if (link->data) {
-                       item= PyUnicode_FromString(link->data);
-                       PyList_Append(ret, item);
-                       Py_DECREF(item);
-               }
-               else {
-                       PyList_Append(ret, Py_None);
-               }
-       }
-
-       /* free memory */
-       BLI_freelistN(images);
-       BLI_freelistN(paths);
-
-       /* return filenames */
-       return ret;
-}
index 75e7494..82059c8 100644 (file)
@@ -1,7 +1,10 @@
 #!/usr/bin/python
 Import ('env')
 
-sources = 'creator.c'
+sources = ['creator.c']
+
+if env['WITH_BF_UNIT_TEST']:
+       sources += env.Glob('tests/*.c')
 
 incs = '#/intern/guardedalloc ../blender/blenlib ../blender/blenkernel'
 incs += ' ../blender/editors/include ../blender/blenloader ../blender/imbuf'
@@ -11,6 +14,10 @@ incs += ' ../kernel/gen_system #/extern/glew/include ../blender/gpu'
 incs += ' ' + env['BF_OPENGL_INC']
 
 defs = []
+
+if env['WITH_BF_UNIT_TEST']:
+       defs.append('WITH_UNIT_TEST')
+
 if env['WITH_BF_QUICKTIME']:
        incs += ' ' + env['BF_QUICKTIME_INC']
        defs.append('WITH_QUICKTIME')
@@ -32,4 +39,4 @@ if env['WITH_BF_PYTHON']:
 else:
        defs.append('DISABLE_PYTHON')
 
-env.BlenderLib ( libname = 'bf_creator', sources = Split(sources), includes = Split(incs), defines = defs, libtype='core', priority = 0 )
+env.BlenderLib ( libname = 'bf_creator', sources = sources, includes = Split(incs), defines = defs, libtype='core', priority = 0 )
index 8e0152b..3a2a0ff 100644 (file)
@@ -338,6 +338,12 @@ int main(int argc, char **argv)
                        exit(0);
                }
 
+#ifdef WITH_UNIT_TEST
+               if (!strcmp(argv[a], "--test")) {
+                       exit(run_tests());
+               }
+#endif
+
                /* end argument processing after -- */
                if (!strcmp( argv[a], "--")){
                        a = argc;
diff --git a/source/creator/tests/alltest.c b/source/creator/tests/alltest.c
new file mode 100644 (file)
index 0000000..2173ecd
--- /dev/null
@@ -0,0 +1,114 @@
+#include <stdlib.h>
+#include <string.h>
+#include <check.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BKE_blender.h"
+#include "BKE_image.h"
+#include "BKE_utildefines.h"
+#include "BKE_global.h"
+
+#include "BLI_listbase.h"
+
+#include "DNA_image_types.h"
+
+char bprogname[FILE_MAXDIR+FILE_MAXFILE];
+char btempdir[FILE_MAXDIR+FILE_MAXFILE];
+
+typedef struct ImageTestData {
+       char *path; /* image filename */
+       char *expect_path; /* file path that we expect */
+       int type; /* image type */
+       int ret;  /* expected function return value */
+} ImageTestData;
+
+/* check that BKE_copy_images manipulates paths correctly */
+START_TEST(test_copy_images)
+{
+       char *dest_dir[] = {"/tmp/", "/tmp", NULL};
+       char **dir;
+       ImageTestData *test;
+
+       /* XXX Windows not tested */    
+#ifdef WIN32
+       static ImageTestData test_data[] = {
+               {"//bar/image.png", "C:\\Temp\\bar\\image.png"},
+               /* TODO add more */
+               {NULL, NULL},
+       };
+       
+       BLI_strncpy(G.sce, "C:\\Temp\untitled.blend", sizeof(G.sce));
+#else
+       /*
+         XXX are these paths possible in image->name?:
+
+         ./foo/image.png
+         ../foo/image.png
+
+         if so, BKE_copy_images currently doesn't support them!
+        */
+       static ImageTestData test_data[] = {
+               {"//bar/image.png", "/tmp/bar/image.png", IMA_TYPE_IMAGE, 1},
+               {"/foo/bar/image.png", "/tmp/image.png", IMA_TYPE_IMAGE, 1},
+               {"//image.png", "/tmp/image.png", IMA_TYPE_IMAGE, 1},
+               {"//../../../foo/bar/image.png", "/tmp/image.png", IMA_TYPE_IMAGE, 1},
+               {"//./foo/bar/image.png", "/tmp/foo/bar/image.png", IMA_TYPE_IMAGE, 1},
+               {"/tmp/image.png", "/tmp/image.png", IMA_TYPE_IMAGE, 1},
+               {"//textures/test/foo/bar/image.png", "/tmp/textures/test/foo/bar/image.png", IMA_TYPE_IMAGE, 1},
+               {"//textures/test/foo/bar/image.png", "", IMA_TYPE_MULTILAYER, 0},
+               {"", "", IMA_TYPE_IMAGE, 0},
+               {NULL, NULL},
+       };
+
+       /* substitute G.sce */
+       BLI_strncpy(G.sce, "/tmp/foo/bar/untitled.blend", sizeof(G.sce));
+#endif
+
+       for (dir = dest_dir; *dir; dir++) {
+               for (test= &test_data[0]; test->path; test++) {
+                       Image image;
+                       char path[FILE_MAX];
+                       int ret;
+
+                       BLI_strncpy(image.name, test->path, sizeof(image.name));
+                       image.type= test->type;
+
+                       ret= BKE_export_image(&image, *dest_dir, path, sizeof(path));
+
+                       /* check if we got correct output */
+                       fail_if(ret != test->ret, "For image with filename %s and type %d, expected %d as return value got %d.",
+                                       test->path, test->type, test->ret, ret);
+                       fail_if(strcmp(path, test->expect_path), "For image with filename %s and type %d, expected path '%s' got '%s'.",
+                                       test->path, test->type, test->expect_path, path);
+               }
+       }
+}
+END_TEST
+
+static Suite *image_suite(void)
+{
+       Suite *s = suite_create("Image");
+
+       /* Core test case */
+       TCase *tc_core = tcase_create("Core");
+       tcase_add_test(tc_core, test_copy_images);
+       suite_add_tcase(s, tc_core);
+
+       return s;
+}
+
+int run_tests()
+{
+       int totfail;
+       Suite *s = image_suite();
+       SRunner *sr = srunner_create(s);
+
+       /* run tests */
+       srunner_run_all(sr, CK_VERBOSE);
+
+       totfail= srunner_ntests_failed(sr);
+       srunner_free(sr);
+
+       return !totfail ? EXIT_SUCCESS : EXIT_FAILURE;
+}
index 8d21316..c3ba9b2 100644 (file)
@@ -161,6 +161,8 @@ def setup_syslibs(lenv):
                ]
 
        syslibs += Split(lenv['BF_FREETYPE_LIB'])
+       if lenv['WITH_BF_UNIT_TEST']:
+               syslibs.append(lenv['BF_CHECK_LIB'])
        if lenv['WITH_BF_PYTHON'] and not lenv['WITH_BF_STATICPYTHON']:
                if lenv['BF_DEBUG'] and lenv['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
                        syslibs.append(lenv['BF_PYTHON_LIB']+'_d')
index f4d79b1..521596e 100755 (executable)
@@ -66,7 +66,8 @@ def validate_arguments(args, bc):
                        'BF_NUMJOBS',
                        'BF_MSVS',
 
-                       'WITH_BF_UNIT_TEST'
+                       'WITH_BF_UNIT_TEST',
+                       'BF_CHECK_LIB',
                        ]
        
        # Have options here that scons expects to be lists
@@ -360,7 +361,8 @@ def read_opts(cfg, args):
                ('BF_NUMJOBS', 'Number of build processes to spawn', '1'),
                ('BF_MSVS', 'Generate MSVS project files and solution', False),
 
-               (BoolVariable('WITH_BF_UNIT_TEST', 'Build unit tests', False))
+               (BoolVariable('WITH_BF_UNIT_TEST', 'Build unit tests', False)),
+               ('BF_CHECK_LIB', 'Check unit testing framework library', 'check'),
 
        ) # end of opts.AddOptions()