Merging r49840 through r49854 from trunk into soc-2011-tomato
authorSergey Sharybin <sergey.vfx@gmail.com>
Sun, 12 Aug 2012 18:39:05 +0000 (18:39 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Sun, 12 Aug 2012 18:39:05 +0000 (18:39 +0000)
24 files changed:
source/blender/blenkernel/BKE_material.h
source/blender/blenkernel/CMakeLists.txt
source/blender/blenkernel/SConscript
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/material.c
source/blender/blenkernel/intern/sequencer.c
source/blender/collada/DocumentImporter.cpp
source/blender/collada/EffectExporter.cpp
source/blender/collada/GeometryExporter.cpp
source/blender/collada/InstanceWriter.cpp
source/blender/collada/MaterialExporter.h
source/blender/collada/MeshImporter.cpp
source/blender/collada/MeshImporter.h
source/blender/collada/collada_utils.cpp
source/blender/collada/collada_utils.h
source/blender/compositor/operations/COM_InpaintOperation.cpp
source/blender/datatoc/datatoc.c
source/blender/editors/object/object_relations.c
source/blender/editors/object/object_select.c
source/blender/editors/space_outliner/outliner_edit.c
source/blender/makesdna/DNA_object_types.h
source/blender/makesrna/intern/rna_main_api.c
source/blender/makesrna/intern/rna_object.c
source/blender/modifiers/intern/MOD_boolean_util.c

index 2407330a237dc3fc7dfb2e870810092bee521108..030af85ba849ddd1e18fe9c3a5b3d5749713fb1b 100644 (file)
@@ -67,10 +67,16 @@ short *give_totcolp(struct Object *ob);
 struct Material ***give_matarar_id(struct ID *id); /* same but for ID's */
 short *give_totcolp_id(struct ID *id);
 
+enum {
+       BKE_MAT_ASSIGN_USERPREF,
+       BKE_MAT_ASSIGN_OBDATA,
+       BKE_MAT_ASSIGN_OBJECT
+};
+
 struct Material *give_current_material(struct Object *ob, short act);
 struct ID *material_from(struct Object *ob, short act);
 void assign_material_id(struct ID *id, struct Material *ma, short act);
-void assign_material(struct Object *ob, struct Material *ma, short act);
+void assign_material(struct Object *ob, struct Material *ma, short act, int assign_type);
 void assign_matarar(struct Object *ob, struct Material ***matar, short totcol);
 
 short find_material_index(struct Object *ob, struct Material *ma);
index 8ae705fa3eb32bbb41a07dac75d34ef0f284276b..38a39ad492d193add768512c544865aff97d6261 100644 (file)
@@ -254,6 +254,7 @@ endif()
 if(WITH_MOD_CLOTH_ELTOPO)
        list(APPEND INC
                ../../../extern/eltopo
+               ../../../extern/eltopo/eltopo3d
        )
        add_definitions(-DWITH_ELTOPO)
 endif()
index 555d95acf881de2b8a468f7a75412def02a11ea0..d1a35b122e8daf552f6e543c1d835504969d9053 100644 (file)
@@ -41,7 +41,8 @@ if env['WITH_BF_PYTHON']:
         defs.append('DEBUG')
 
 if env['WITH_BF_ELTOPO']:
-    incs += ' ../../../extern/eltopo'
+    incs += ' #/extern/eltopo'
+    incs += ' #/extern/eltopo/eltopo3d'
     defs.append('WITH_ELTOPO')
         
 if env['WITH_BF_QUICKTIME']:
index 87ebc597ecd6ff16d3b15e442c23bd3adc297d99..b22e24e15d4af9c6df486067706ee1b1444836bb 100644 (file)
@@ -2596,7 +2596,8 @@ static void dag_id_flush_update(Scene *sce, ID *id)
        if (id) {
                idtype = GS(id->name);
 
-               if (ELEM8(idtype, ID_ME, ID_CU, ID_MB, ID_LA, ID_LT, ID_CA, ID_AR, ID_SPK)) {
+
+               if (OB_DATA_SUPPORT_ID(idtype)) {
                        for (obt = bmain->object.first; obt; obt = obt->id.next) {
                                if (!(ob && obt == ob) && obt->data == id) {
                                        obt->recalc |= OB_RECALC_DATA;
index f97dd2f859dd412e1cd79862f0bdc122e7392653..71e3feb9ced016f3196377eab47ac41824fd4c53 100644 (file)
@@ -494,6 +494,9 @@ short *give_totcolp(Object *ob)
 /* same as above but for ID's */
 Material ***give_matarar_id(ID *id)
 {
+       /* ensure we don't try get materials from non-obdata */
+       BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
+
        switch (GS(id->name)) {
                case ID_ME:
                        return &(((Mesh *)id)->mat);
@@ -510,6 +513,9 @@ Material ***give_matarar_id(ID *id)
 
 short *give_totcolp_id(ID *id)
 {
+       /* ensure we don't try get materials from non-obdata */
+       BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
+
        switch (GS(id->name)) {
                case ID_ME:
                        return &(((Mesh *)id)->totcol);
@@ -526,6 +532,9 @@ short *give_totcolp_id(ID *id)
 
 static void data_delete_material_index_id(ID *id, short index)
 {
+       /* ensure we don't try get materials from non-obdata */
+       BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
+
        switch (GS(id->name)) {
                case ID_ME:
                        BKE_mesh_delete_material_index((Mesh *)id, index);
@@ -765,11 +774,12 @@ void assign_material_id(ID *id, Material *ma, short act)
        test_object_materials(id);
 }
 
-void assign_material(Object *ob, Material *ma, short act)
+void assign_material(Object *ob, Material *ma, short act, int assign_type)
 {
        Material *mao, **matar, ***matarar;
        char *matbits;
        short *totcolp;
+       char bit=0;
 
        if (act > MAXMAT) return;
        if (act < 1) act = 1;
@@ -796,8 +806,29 @@ void assign_material(Object *ob, Material *ma, short act)
                *matarar = matar;
                *totcolp = act;
        }
-       
+
+       // Determine the object/mesh linking
+       if (assign_type == BKE_MAT_ASSIGN_USERPREF && ob->actcol) {
+               /* copy from previous material */
+               bit = ob->matbits[ob->actcol - 1];
+       }
+       else {
+               switch(assign_type) {
+                       case BKE_MAT_ASSIGN_OBDATA:
+                               bit = 0;
+                               break;
+                       case BKE_MAT_ASSIGN_OBJECT:
+                               bit = 1;
+                               break;
+                       case BKE_MAT_ASSIGN_USERPREF:
+                       default:
+                               bit = (U.flag & USER_MAT_ON_OB) ? 1 : 0;
+                               break;
+               }
+       }
+
        if (act > ob->totcol) {
+               /* Need more space in the material arrays */
                matar = MEM_callocN(sizeof(void *) * act, "matarray2");
                matbits = MEM_callocN(sizeof(char) * act, "matbits1");
                if (ob->totcol) {
@@ -809,17 +840,12 @@ void assign_material(Object *ob, Material *ma, short act)
                ob->mat = matar;
                ob->matbits = matbits;
                ob->totcol = act;
-
-               /* copy object/mesh linking, or assign based on userpref */
-               if (ob->actcol)
-                       ob->matbits[act - 1] = ob->matbits[ob->actcol - 1];
-               else
-                       ob->matbits[act - 1] = (U.flag & USER_MAT_ON_OB) ? 1 : 0;
        }
        
        /* do it */
 
-       if (ob->matbits[act - 1]) {   /* in object */
+       ob->matbits[act - 1] = bit;
+       if (bit == 1) {   /* in object */
                mao = ob->mat[act - 1];
                if (mao) mao->id.us--;
                ob->mat[act - 1] = ma;
@@ -845,7 +871,7 @@ void assign_matarar(struct Object *ob, struct Material ***matar, short totcol)
 
        /* now we have the right number of slots */
        for (i = 0; i < totcol; i++)
-               assign_material(ob, (*matar)[i], i + 1);
+               assign_material(ob, (*matar)[i], i + 1, BKE_MAT_ASSIGN_USERPREF);
 
        if (actcol_orig > ob->totcol)
                actcol_orig = ob->totcol;
@@ -879,7 +905,7 @@ int object_add_material_slot(Object *ob)
        if (ob == NULL) return FALSE;
        if (ob->totcol >= MAXMAT) return FALSE;
        
-       assign_material(ob, NULL, ob->totcol + 1);
+       assign_material(ob, NULL, ob->totcol + 1, BKE_MAT_ASSIGN_USERPREF);
        ob->actcol = ob->totcol;
        return TRUE;
 }
index 45259b5dbc9f4b4d0e9612805f05ada717054e2f..0432e7a62a2c69eb4933b604749583183a3bd458 100644 (file)
@@ -136,8 +136,6 @@ static void free_proxy_seq(Sequence *seq)
                IMB_free_anim(seq->strip->proxy->anim);
                seq->strip->proxy->anim = NULL;
        }
-
-       BKE_sequencer_cache_cleanup_sequence(seq);
 }
 
 static void seq_free_strip(Strip *strip)
@@ -205,6 +203,8 @@ void BKE_sequence_free(Scene *scene, Sequence *seq)
                seq_free_animdata(scene, seq);
        }
 
+       BKE_sequencer_cache_cleanup_sequence(seq);
+
        MEM_freeN(seq);
 }
 
@@ -1640,6 +1640,13 @@ static void color_balance(SeqRenderData context, Sequence *seq, ImBuf *ibuf, flo
        IMB_processor_apply_threaded(ibuf->y, sizeof(ColorBalanceThread), &init_data,
                                  color_balance_init_handle, color_balance_do_thread);
 
+       /* color balance either happens on float buffer or byte buffer, but never on both,
+        * free byte buffer if there's float buffer since float buffer would be used for
+        * color balance in favor of byte buffer
+        */
+       if (ibuf->rect_float && ibuf->rect)
+               imb_freerectImBuf(ibuf);
+
        if (init_data.mask)
                IMB_freeImBuf(init_data.mask);
 }
index 7cfce9d25266bc23f187d2a729df24124dd1bf54..60b03a211ba30816504fbf66f7731f16f4a14b11 100644 (file)
@@ -208,6 +208,10 @@ void DocumentImporter::finish()
                        write_node(roots[i], NULL, sce, NULL, false);
                }
        }
+
+
+       mesh_importer.optimize_material_assignements();
+
        armature_importer.set_tags_map(this->uid_tags_map);
        armature_importer.make_armatures(mContext);
 
index 1eee797b51c39a95c662519105d3abd3edd620c5..2d9ccc3e3ef5ad84f2cdc93440bff4d22e23007d 100644 (file)
 #include "DocumentExporter.h"
 #include "MaterialExporter.h"
 
-#include "DNA_mesh_types.h"
-#include "DNA_texture_types.h"
-#include "DNA_world_types.h"
-
-#include "BKE_customdata.h"
-#include "BKE_mesh.h"
-#include "BKE_material.h"
-
 #include "collada_internal.h"
 #include "collada_utils.h"
 
+extern "C" {
+       #include "DNA_mesh_types.h"
+       #include "DNA_texture_types.h"
+       #include "DNA_world_types.h"
+
+       #include "BKE_customdata.h"
+       #include "BKE_mesh.h"
+       #include "BKE_material.h"
+}
+
 // OB_MESH is assumed
 static std::string getActiveUVLayerName(Object *ob)
 {
index d30f9b86a5a911e52f371ad30d3a0e20959db182..29ffcf53ee96467f8282f9a83dcd655f1e455b34 100644 (file)
@@ -42,12 +42,11 @@ extern "C" {
        #include "BKE_main.h"
        #include "BKE_global.h"
        #include "BKE_library.h"
+       #include "BKE_customdata.h"
+       #include "BKE_material.h"
+       #include "BKE_mesh.h"
 }
 
-
-#include "BKE_customdata.h"
-#include "BKE_material.h"
-#include "BKE_mesh.h"
 #include "collada_internal.h"
 #include "collada_utils.h"
 
index 5908037d7826c9fa12ffb651c932b099ca3c0451..be45d5295e5d9a4c6daf392aa74f4d27eae4698b 100644 (file)
 
 #include "COLLADASWInstanceMaterial.h"
 
-#include "BKE_customdata.h"
-#include "BKE_material.h"
-
-#include "DNA_mesh_types.h"
+extern "C" {
+       #include "BKE_customdata.h"
+       #include "BKE_material.h"
+       #include "DNA_mesh_types.h"
+}
 
 #include "InstanceWriter.h"
-
 #include "collada_internal.h"
 #include "collada_utils.h"
 
index f65c8849c84ba4eadadefd86fc8a096801febaee..09d10846b53acf38697d29d962d40a9c2be0bf80 100644 (file)
 #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"
+extern "C" {
+       #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"
index 8ee30f691eedf4a9eb2376a4b149fd26eff395db..5593fe993f4a38e4ab3dec99243064569f426e82 100644 (file)
 #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 "BLI_edgehash.h"
-
-#include "MEM_guardedalloc.h"
+       #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 "BLI_edgehash.h"
+
+       #include "MEM_guardedalloc.h"
 }
 
 #include "ArmatureImporter.h"
@@ -988,6 +988,139 @@ MTex *MeshImporter::assign_textures_to_uvlayer(COLLADAFW::TextureCoordinateBindi
        return color_texture;
 }
 
+/**
+ * this function checks if both objects have the same
+ * materials assigned to Object (in the same order)
+ * returns true if condition matches, otherwise false;
+ **/
+static bool bc_has_same_material_configuration(Object *ob1, Object *ob2)
+{
+       if (ob1->totcol != ob2->totcol) return false; // not same number of materials
+       if (ob1->totcol == 0) return false; // no material at all
+       
+       for(int index=0; index < ob1->totcol; index++) {
+               if (ob1->matbits[index] != ob2->matbits[index]) return false; // shouldn't happen
+               if (ob1->matbits[index] == 0) return false; // shouldn't happen
+               if (ob1->mat[index] != ob2->mat[index]) return false; // different material assignment
+       }
+       return true;
+}
+
+
+/**
+ *
+ * Caution here: This code assumes tha all materials are assigned to Object
+ * and no material is assigned to Data.
+ * That is true right after the objects have been imported.
+ *
+ **/
+static void bc_copy_materials_to_data(Object *ob, Mesh *me)
+{
+       for (int index = 0; index < ob->totcol; index++) {
+               ob->matbits[index] = 0;
+               me->mat[index] = ob->mat[index];
+       }
+}
+
+/**
+ *
+ * Remove all references to materials from the object
+ *
+ **/
+static void bc_remove_materials_from_object(Object *ob, Mesh *me)
+{
+       for (int index = 0; index < ob->totcol; index++) {
+               ob->matbits[index] = 0;
+               ob->mat[index] = NULL;
+       }
+}
+
+/**
+ * Returns the list of Users of the given Mesh object.
+ * Note: This function uses the object user flag to control
+ * which objects have already been processed.
+ **/
+std::vector<Object *> MeshImporter::get_all_users_of(Mesh *reference_mesh)
+{
+       std::vector<Object *> mesh_users;
+       for (std::vector<Object *>::iterator it = imported_objects.begin();
+            it != imported_objects.end(); ++it)
+       {
+               Object *ob = (*it);
+               if (bc_is_marked(ob)) {
+                       bc_remove_mark(ob);
+                       Mesh *me = (Mesh *) ob->data;
+                       if (me == reference_mesh)
+                               mesh_users.push_back(ob);
+               }
+       }
+       return mesh_users;
+}
+
+/**
+ *
+ * During import all materials have been assigned to Object.
+ * Now we iterate over the imported objects and optimize
+ * the assignements as follows:
+ *
+ * for each imported geometry:
+ *     if number of users is 1:
+ *         get the user (object)
+ *         move the materials from Object to Data
+ *     else:
+ *         determine which materials are assigned to the first user
+ *         check if all other users have the same materials in the same order
+ *         if the check is positive:
+ *             Add the materials of the first user to the geometry
+ *             adjust all other users accordingly.
+ *
+ **/
+void MeshImporter::optimize_material_assignements()
+{
+       for (std::vector<Object *>::iterator it = imported_objects.begin();
+            it != imported_objects.end(); ++it)
+       {
+               Object *ob = (*it);
+               Mesh *me = (Mesh *) ob->data;
+               if (me->id.us==1) {
+                       bc_copy_materials_to_data(ob,me);
+                       bc_remove_materials_from_object(ob,me);
+                       bc_remove_mark(ob);
+               }
+               else if (me->id.us > 1)
+               {
+                       bool can_move = true;
+                       std::vector<Object *> mesh_users = get_all_users_of(me);
+                       if (mesh_users.size() > 1)
+                       {
+                               Object *ref_ob = mesh_users[0];
+                               for (int index = 1; index < mesh_users.size(); index++) {
+                                       if (!bc_has_same_material_configuration(ref_ob, mesh_users[index])) {
+                                               can_move = false;
+                                               break;
+                                       }
+                               }
+                               if (can_move) {
+                                       bc_copy_materials_to_data(ref_ob,me);
+                                       for (int index = 0; index < mesh_users.size(); index++) {
+                                               Object *object = mesh_users[index];
+                                               bc_remove_materials_from_object(object,me);
+                                               bc_remove_mark(object);
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
+/**
+ * We do not know in advance which objects will share geometries.
+ * And we do not know either if the objects which share geometries
+ * come along with different materials. So we first create the objects
+ * and assign the materials to Object, then in a later cleanup we decide
+ * which materials shall be moved to the created geometries. Also see
+ * optimize_material_assignements() above.
+ */
 MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial,
                                               std::map<COLLADAFW::UniqueId, Material *>& uid_material_map,
                                               Object *ob, const COLLADAFW::UniqueId *geom_uid,
@@ -1003,21 +1136,16 @@ MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmateri
                fprintf(stderr, "Cannot find material by UID.\n");
                return NULL;
        }
-       
-       // different nodes can point to same geometry, but still also specify the same materials
-       // again. Make sure we don't overwrite them on the next occurrences, so keep list of
-       // what we already have handled.
-       std::multimap<COLLADAFW::UniqueId, COLLADAFW::UniqueId>::iterator it;
-       it = materials_mapped_to_geom.find(*geom_uid);
-       while (it != materials_mapped_to_geom.end()) {
-               if (it->second == ma_uid && it->first == *geom_uid) return NULL;  // do nothing if already found
-               it++;
-       }
+
        // first time we get geom_uid, ma_uid pair. Save for later check.
        materials_mapped_to_geom.insert(std::pair<COLLADAFW::UniqueId, COLLADAFW::UniqueId>(*geom_uid, ma_uid));
        
        Material *ma = uid_material_map[ma_uid];
-       assign_material(ob, ma, ob->totcol + 1);
+
+       // Attention! This temporaly assigns material to object on purpose!
+       // See note above.
+       ob->actcol=0;
+       assign_material(ob, ma, mat_index + 1, BKE_MAT_ASSIGN_OBJECT); 
        
        COLLADAFW::TextureCoordinateBindingArray& tex_array = 
            cmaterial.getTextureCoordinateBindingArray();
@@ -1101,9 +1229,12 @@ Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::Insta
        
        // add object
        Object *ob = bc_add_object(scene, OB_MESH, name);
+       bc_set_mark(ob); // used later for material assignement optimization
+
 
        // store object pointer for ArmatureImporter
        uid_object_map[*geom_uid] = ob;
+       imported_objects.push_back(ob);
        
        // replace ob->data freeing the old one
        Mesh *old_mesh = (Mesh *)ob->data;
index e4c1aca395a0360fc0203504144a12c49c0a06c6..2cac26d5329f30bc43843556b969004814a7a09d 100644 (file)
 #include "COLLADAFWTypes.h"
 #include "COLLADAFWUniqueId.h"
 
+#include "ArmatureImporter.h"
+#include "collada_utils.h"
+
+extern "C" {
+#include "BLI_edgehash.h"
 #include "DNA_material_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_texture_types.h"
 
-#include "ArmatureImporter.h"
-#include "collada_utils.h"
-
-extern "C" {
-#include "BLI_edgehash.h"
 }
 
 // only for ArmatureImporter to "see" MeshImporter::get_object_by_geom_uid
@@ -85,6 +85,7 @@ private:
 
        std::map<COLLADAFW::UniqueId, Mesh*> uid_mesh_map; // geometry unique id-to-mesh map
        std::map<COLLADAFW::UniqueId, Object*> uid_object_map; // geom uid-to-object
+       std::vector<Object*> imported_objects; // list of imported objects
        // this structure is used to assign material indices to faces
        // it holds a portion of Mesh faces and corresponds to a DAE primitive list (<triangles>, <polylist>, etc.)
        struct Primitive {
@@ -140,7 +141,9 @@ private:
        void get_vector(float v[3], COLLADAFW::MeshVertexData& arr, int i, int stride);
 
        bool flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& nor, int count);
-       
+
+       std::vector<Object *> get_all_users_of(Mesh *reference_mesh);
+
 public:
 
        MeshImporter(UnitConverter *unitconv, ArmatureImporter *arm, Scene *sce);
@@ -152,7 +155,9 @@ public:
        MTex *assign_textures_to_uvlayer(COLLADAFW::TextureCoordinateBinding &ctexture,
                                                                         Mesh *me, TexIndexTextureArrayMap& texindex_texarray_map,
                                                                         MTex *color_texture);
-       
+
+       void optimize_material_assignements();
+
        MTFace *assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial,
                                                                        std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
                                                                        Object *ob, const COLLADAFW::UniqueId *geom_uid, 
index 955d699d96c8362cf463fce45ab1f0d790d281b5..018d66c6f550ba38259f2f60b731794966f994d3 100644 (file)
@@ -230,6 +230,11 @@ void bc_remove_mark(Object *ob)
        ob->id.flag &= ~LIB_DOIT;
 }
 
+void bc_set_mark(Object *ob)
+{
+       ob->id.flag |= LIB_DOIT;
+}
+
 // Use bubble sort algorithm for sorting the export set
 void bc_bubble_sort_by_Object_name(LinkNode *export_set)
 {
index 5f72581f584f1dcf6f53b674225f9f28ba5fd15e..b52115722fe6c48a80fb78297602a01124132c9a 100644 (file)
@@ -67,6 +67,7 @@ extern bool bc_has_object_type(LinkNode *export_set, short obtype);
 
 extern int bc_is_marked(Object *ob);
 extern void bc_remove_mark(Object *ob);
+extern void bc_set_mark(Object *ob);
 
 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);
index eb732cc2b80f5f6b5b82d4743c0e25a57940c757..b0e9c601e077ddd6c3ea29bfa79d3ccc65d4df5f 100644 (file)
@@ -57,7 +57,7 @@ void InpaintSimpleOperation::initExecution()
        this->initMutex();
 }
 
-void InpaintSimpleOperation::clamp_xy(int & x, int & y) 
+void InpaintSimpleOperation::clamp_xy(int &x, int &y)
 {
        int width = this->getWidth();
        int height = this->getHeight();
@@ -97,7 +97,7 @@ int InpaintSimpleOperation::mdist(int x, int y)
        return this->m_manhatten_distance[y * width + x];
 }
 
-bool InpaintSimpleOperation::next_pixel(int & x, int & y, int & curr, int iters)
+bool InpaintSimpleOperation::next_pixel(int &x, int &y, int & curr, int iters)
 {
        int width = this->getWidth();
 
@@ -110,7 +110,7 @@ bool InpaintSimpleOperation::next_pixel(int & x, int & y, int & curr, int iters)
        x = r % width;
        y = r / width;
 
-       if (mdist(x, y) > iters) {
+       if (this->mdist(x, y) > iters) {
                return false;
        }
        
@@ -176,11 +176,9 @@ void InpaintSimpleOperation::calc_manhatten_distance()
 
 void InpaintSimpleOperation::pix_step(int x, int y)
 {
-       int d = this->mdist(x, y);
-
-       float n = 0;
-
+       const int d = this->mdist(x, y);
        float pix[3] = {0.0f, 0.0f, 0.0f};
+       float pix_divider = 0.0f;
 
        for (int dx = -1; dx <= 1; dx++) {
                for (int dy = -1; dy <= 1; dy++) {
@@ -202,13 +200,19 @@ void InpaintSimpleOperation::pix_step(int x, int y)
                                        }
 
                                        madd_v3_v3fl(pix, this->get_pixel(x_ofs, y_ofs), weight);
-                                       n += weight;
+                                       pix_divider += weight;
                                }
                        }
                }
        }
 
-       mul_v3_v3fl(this->get_pixel(x, y), pix, 1.0f / n);
+       float *output = this->get_pixel(x, y);
+       if (pix_divider != 0.0f) {
+               mul_v3_fl(pix, 1.0f / pix_divider);
+               /* use existing pixels alpha to blend into */
+               interp_v3_v3v3(output, pix, output, output[3]);
+               output[3] = 1.0f;
+       }
 
        this->get_pixel(x, y)[3] = 1.0f;
 }
@@ -225,14 +229,14 @@ void *InpaintSimpleOperation::initializeTileData(rcti *rect)
                this->m_cached_buffer = new float[this->getWidth() * this->getHeight() * COM_NUMBER_OF_CHANNELS];
                memcpy(this->m_cached_buffer, buf->getBuffer(), this->getWidth() * this->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float));
 
-               calc_manhatten_distance();
+               this->calc_manhatten_distance();
 
                int curr = 0;
                int x, y;
 
        
-               while (next_pixel(x, y, curr, this->m_iterations)) {
-                       pix_step(x, y);
+               while (this->next_pixel(x, y, curr, this->m_iterations)) {
+                       this->pix_step(x, y);
                }
                this->m_cached_buffer_ready = true;
        }
index d074917a545dcce0b6dbbac164e7f30d0385a5c4..a7da037ff16befe83b536f2d3d5f32ef875584b3 100644 (file)
@@ -81,19 +81,6 @@ int main(int argc, char **argv)
 
        sprintf(sizest, "%d", (int)size);
 
-#ifdef VERBOSE
-       printf("Input filesize is %d, Output size should be %d\n",
-              (int)size,
-              (int)(((int)size) * 4 +
-                    strlen("/* DataToC output of file <> */\n\n") +
-                    strlen("char datatoc_[] = {\"") +
-                    strlen("\"};\n") +
-                    (strlen(argv[1]) * 3) +
-                    strlen(sizest) +
-                    strlen("int datatoc__size = ;\n") +
-                    (((int)(size / 256) + 1) * 5)));
-#endif
-
        fpout = fopen(argv[2], "w");
        if (!fpout) {
                fprintf(stderr, "Unable to open output <%s>\n", argv[2]);
@@ -104,6 +91,8 @@ int main(int argc, char **argv)
        fprintf(fpout, "int datatoc_%s_size = %s;\n", argv[1], sizest);
        fprintf(fpout, "char datatoc_%s[] = {\n", argv[1]);
        while (size--) {
+               /* if we want to open in an editor
+                * this is nicer to avoid very long lines */
 #ifdef VERBOSE
                if (size % 32 == 31) {
                        fprintf(fpout, "\n");
@@ -114,7 +103,10 @@ int main(int argc, char **argv)
                fprintf(fpout, "%3d,", getc(fpin));
        }
 
-       fprintf(fpout, "\n};\n\n");
+       /* trailing NULL terminator, this isnt needed in some cases and
+        * won't be taken into account by the size variable, but its useful when dealing with
+        * NULL terminated string data */
+       fprintf(fpout, "0\n};\n\n");
 
        fclose(fpin);
        fclose(fpout);
index 561ebafc0d7be1c42ff76a4046a8e49eb1753170..d8c964ff2dfb369fe1f18f2a88367360cef07dfa 100644 (file)
@@ -1368,7 +1368,7 @@ static int make_links_data_exec(bContext *C, wmOperator *op)
                                                /* new approach, using functions from kernel */
                                                for (a = 0; a < ob_src->totcol; a++) {
                                                        Material *ma = give_current_material(ob_src, a + 1);
-                                                       assign_material(ob_dst, ma, a + 1); /* also works with ma==NULL */
+                                                       assign_material(ob_dst, ma, a + 1, BKE_MAT_ASSIGN_USERPREF); /* also works with ma==NULL */
                                                }
                                                break;
                                        case MAKE_LINKS_ANIMDATA:
@@ -1692,7 +1692,7 @@ static void single_mat_users(Scene *scene, int flag, int do_textures)
                                                BKE_copy_animdata_id_action(&man->id);
                                                
                                                man->id.us = 0;
-                                               assign_material(ob, man, a);
+                                               assign_material(ob, man, a, BKE_MAT_ASSIGN_USERPREF);
 
                                                if (do_textures) {
                                                        for (b = 0; b < MAX_MTEX; b++) {
@@ -2044,7 +2044,7 @@ static int drop_named_material_invoke(bContext *C, wmOperator *op, wmEvent *even
        if (base == NULL || ma == NULL)
                return OPERATOR_CANCELLED;
        
-       assign_material(base->object, ma, 1);
+       assign_material(base->object, ma, 1, BKE_MAT_ASSIGN_USERPREF);
        
        DAG_ids_flush_update(bmain, 0);
        WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C));
index ac3210348de62924b364287fdf5c98323760ca14..ff7728d4f68d422c8e8364a4e7118a9b9afa3136 100644 (file)
@@ -388,21 +388,22 @@ static int object_select_all_by_library_obdata(bContext *C, Library *lib)
 
 void ED_object_select_linked_by_id(bContext *C, ID *id)
 {
-       int gs = GS(id->name);
+       int idtype = GS(id->name);
        int changed = FALSE;
 
-       if (ELEM8(gs, ID_ME, ID_CU, ID_MB, ID_LT, ID_LA, ID_CA, ID_TXT, ID_SPK)) {
+       if (OB_DATA_SUPPORT_ID(idtype)) {
                changed = object_select_all_by_obdata(C, id);
        }
-       else if (gs == ID_MA) {
+       else if (idtype == ID_MA) {
                changed = object_select_all_by_material_texture(C, FALSE, (Material *)id, NULL);
        }
-       else if (gs == ID_LI) {
+       else if (idtype == ID_LI) {
                changed = object_select_all_by_library(C, (Library *) id);
        }
 
-       if (changed)
+       if (changed) {
                WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, CTX_data_scene(C));
+       }
 }
 
 static int object_select_linked_exec(bContext *C, wmOperator *op)
index 0388ba86b84d82d820043b89f20248a98b3678e0..4fa8686bce3dab4b076d1cbdb5c7d7160a7611cd 100644 (file)
@@ -1851,7 +1851,7 @@ static int material_drop_invoke(bContext *C, wmOperator *op, wmEvent *event)
                        return OPERATOR_CANCELLED;
                }
 
-               assign_material(ob, ma, ob->totcol + 1);
+               assign_material(ob, ma, ob->totcol + 1, BKE_MAT_ASSIGN_USERPREF);
 
                DAG_ids_flush_update(bmain, 0);
                WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C));         
index 3da6d0fc99d5a8cca8e16a03a8346e01a41dfa1a..597103a78df6b0a08d4f710991671d445a09363a 100644 (file)
@@ -343,6 +343,10 @@ typedef struct DupliObject {
 #define OB_TYPE_SUPPORT_EDITMODE(_type) \
        (ELEM7(_type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE))
 
+/* is this ID type used as object data */
+#define OB_DATA_SUPPORT_ID(_id_type) \
+       (ELEM8(_id_type, ID_ME, ID_CU, ID_MB, ID_LA, ID_SPK, ID_CA, ID_LT, ID_AR))
+
 /* partype: first 4 bits: type */
 #define PARTYPE                        15
 #define PAROBJECT              0
index c702972b3b71dfc2be3eae2c1ee45a2385c5031b..59eae3259b4a4c9cdc34d4873e3674540eafe95a 100644 (file)
@@ -140,6 +140,7 @@ Object *rna_Main_objects_new(Main *UNUSED(bmain), ReportList *reports, const cha
        Object *ob;
        int type = OB_EMPTY;
        if (data) {
+               /* keep in sync with OB_DATA_SUPPORT_ID() macro */
                switch (GS(data->name)) {
                        case ID_ME:
                                type = OB_MESH;
index 7aedbf40eba6d1df6fac011a48c125071cb3e47b..e1f45e4de17cab14ffa05df286f0e83ca31db57a 100644 (file)
@@ -355,10 +355,14 @@ static void rna_Object_data_set(PointerRNA *ptr, PointerRNA value)
                set_mesh(ob, (Mesh *)id);
        }
        else {
-               if (ob->data)
+               if (ob->data) {
                        id_us_min((ID *)ob->data);
-               if (id)
+               }
+               if (id) {
+                       /* no need to type-check here ID. this is done in the _typef() function */
+                       BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
                        id_us_plus(id);
+               }
 
                ob->data = id;
                test_object_materials(id);
@@ -374,6 +378,7 @@ static StructRNA *rna_Object_data_typef(PointerRNA *ptr)
 {
        Object *ob = (Object *)ptr->data;
 
+       /* keep in sync with OB_DATA_SUPPORT_ID() macro */
        switch (ob->type) {
                case OB_EMPTY: return &RNA_Image;
                case OB_MESH: return &RNA_Mesh;
@@ -658,7 +663,7 @@ static void rna_Object_active_material_set(PointerRNA *ptr, PointerRNA value)
        Object *ob = (Object *)ptr->id.data;
 
        DAG_id_tag_update(value.data, 0);
-       assign_material(ob, value.data, ob->actcol);
+       assign_material(ob, value.data, ob->actcol, BKE_MAT_ASSIGN_USERPREF);
 }
 
 static void rna_Object_active_particle_system_index_range(PointerRNA *ptr, int *min, int *max,
@@ -815,7 +820,7 @@ static void rna_MaterialSlot_material_set(PointerRNA *ptr, PointerRNA value)
        Object *ob = (Object *)ptr->id.data;
        int index = (Material **)ptr->data - ob->mat;
 
-       assign_material(ob, value.data, index + 1);
+       assign_material(ob, value.data, index + 1, BKE_MAT_ASSIGN_USERPREF);
 }
 
 static int rna_MaterialSlot_link_get(PointerRNA *ptr)
index 9ff35c227de3c107c4dabfd422d592a8c808ef03..bded11ddfa7f3ab6329ae75883f457fb2a09cd0f 100644 (file)
@@ -632,7 +632,7 @@ int NewBooleanMesh(Scene *scene, Base *base, Base *base_select, int int_op_type)
 
        /* add materials to object */
        for (a = 0; a < totmat; a++)
-               assign_material(ob_new, mat[a], a + 1);
+               assign_material(ob_new, mat[a], a + 1, BKE_MAT_ASSIGN_USERPREF);
 
        MEM_freeN(mat);