bugfix [#20639] BF25_SVN_25888 and below - OBJ and 3DS import fails
authorCampbell Barton <ideasman42@gmail.com>
Sun, 17 Jan 2010 20:06:34 +0000 (20:06 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sun, 17 Jan 2010 20:06:34 +0000 (20:06 +0000)
blender supports type changing for textures in a way that python doesnt.
add a new general function.

Example usage:
 tex = bpy.data.textures.new("Foo")
 tex.type = 'IMAGE'
 tex = tex.recast_type()

Macro to give the number of users accounting for fake user.
 ID_REAL_USERS(id)
Use this so you can remove a datablock if it has a fake users as well as apply transformations to it in the 3D view.

Move api function bpy.data.add_texture() --> bpy.data.textures.new()/remove()

12 files changed:
release/scripts/io/import_scene_3ds.py
release/scripts/io/import_scene_obj.py
source/blender/blenkernel/BKE_deform.h
source/blender/editors/object/object_transform.c
source/blender/makesdna/DNA_ID.h
source/blender/makesrna/RNA_access.h
source/blender/makesrna/RNA_enum_types.h
source/blender/makesrna/RNA_types.h
source/blender/makesrna/intern/rna_access.c
source/blender/makesrna/intern/rna_main_api.c
source/blender/makesrna/intern/rna_texture.c
source/blender/python/intern/bpy_rna.c

index ed94d133ccb52c79d8c4c1dbfbdbc17e67e4413c..971d62d8e15fb431a79b8cb9304ebdde5cd75401 100644 (file)
@@ -507,8 +507,9 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
         return [float(col)/255 for col in struct.unpack('<3B', temp_data)] # data [0,1,2] == rgb
 
     def read_texture(new_chunk, temp_chunk, name, mapto):
-        new_texture = bpy.data.add_texture('Diffuse')
+        new_texture = bpy.data.textures.new('Diffuse')
         new_texture.type = 'IMAGE'
+        new_texture = new_texture.recast_type()
 
         img = None
         while (new_chunk.bytes_read < new_chunk.length):
index 5d2d475c7c651bcc51bb2132d6b66c03214852aa..c703a9789bfd1fa15d254dc92e1cc0bf8808ff02 100644 (file)
@@ -367,8 +367,9 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_
     #==================================================================================#
     def load_material_image(blender_material, context_material_name, imagepath, type):
 
-        texture= bpy.data.add_texture(type)
+        texture= bpy.data.textures.new(type)
         texture.type= 'IMAGE'
+        texture = texture.recast_type() # Workaround for limitation in rna api.
 #              texture= bpy.data.textures.new(type)
 #              texture.setType('Image')
 
index d9cf6bc8feb6530ba696c02e77aa628c6ed93c08..59acea3c552fe37b867c442d99c74a7d4d57bfd9 100644 (file)
@@ -47,7 +47,7 @@ int get_defgroup_num (struct Object *ob, struct bDeformGroup *dg);
 int *get_defgroup_flip_map(struct Object *ob);
 int get_named_vertexgroup_num (Object *ob, const char *name);
 void unique_vertexgroup_name (struct bDeformGroup *dg, struct Object *ob);
-void flip_vertexgroup_name (char *name_r, const char *name, int strip_number);
+void flip_vertexgroup_name (char *name, const char *from_name, int strip_number);
 
 float deformvert_get_weight(const struct MDeformVert *dvert, int group_num);
 float vertexgroup_get_vertex_weight(const struct MDeformVert *dvert, int index, int group_num);
index 9e4cc0121716d96b85dbba4a13910d7127813dcb..15ed20c783e67a5f29c7947ce10ae184f07af654 100644 (file)
@@ -411,7 +411,7 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo
                if(ob->type==OB_MESH) {
                        me= ob->data;
                        
-                       if(me->id.us>1) {
+                       if(ID_REAL_USERS(me) > 1) {
                                BKE_report(reports, RPT_ERROR, "Can't apply to a multi user mesh, doing nothing.");
                                return OPERATOR_CANCELLED;
                        }
@@ -419,7 +419,7 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo
                else if(ob->type==OB_ARMATURE) {
                        arm= ob->data;
                        
-                       if(arm->id.us>1) {
+                       if(ID_REAL_USERS(arm) > 1) {
                                BKE_report(reports, RPT_ERROR, "Can't apply to a multi user armature, doing nothing.");
                                return OPERATOR_CANCELLED;
                        }
@@ -427,7 +427,7 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo
                else if(ELEM(ob->type, OB_CURVE, OB_SURF)) {
                        cu= ob->data;
                        
-                       if(cu->id.us>1) {
+                       if(ID_REAL_USERS(cu) > 1) {
                                BKE_report(reports, RPT_ERROR, "Can't apply to a multi user curve, doing nothing.");
                                return OPERATOR_CANCELLED;
                        }
@@ -984,7 +984,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
                                
                                if (arm->id.lib) {
                                        tot_lib_error++;
-                               } else if(arm->id.us>1) {
+                               } else if(ID_REAL_USERS(arm) > 1) {
                                        /*BKE_report(op->reports, RPT_ERROR, "Can't apply to a multi user armature");
                                        return;*/
                                        tot_multiuser_arm_error++;
index 8c835dd7ca7113556b4bb6d5d0b25089384f5ff5..1abc9cd451489f1f2ad7826fd6307e7b1cdf5d44 100644 (file)
@@ -198,6 +198,8 @@ typedef struct PreviewImage {
                        /* fluidsim Ipo */
 #define ID_FLUIDSIM    MAKE_ID2('F', 'S')
 
+#define ID_REAL_USERS(id) (((ID *)id)->us - ((((ID *)id)->flag & LIB_FAKEUSER) ? 1:0))
+
 /* id->flag: set frist 8 bits always at zero while reading */
 #define LIB_LOCAL              0
 #define LIB_EXTERN             1
index 3be97710dd54642d412da85f8f41c14fda6357db..d8e045f8c802129482eea039546b0fada48ccb17 100644 (file)
@@ -569,6 +569,7 @@ void RNA_id_pointer_create(struct ID *id, PointerRNA *r_ptr);
 void RNA_pointer_create(struct ID *id, StructRNA *type, void *data, PointerRNA *r_ptr);
 
 void RNA_blender_rna_pointer_create(PointerRNA *r_ptr);
+void RNA_pointer_recast(PointerRNA *ptr, PointerRNA *r_ptr);
 
 extern PointerRNA PointerRNA_NULL;
 
index 55ebf014b645eea0e660e61ba63e30be965d0fec..88be81fb6911851a299db8a848638b923c3650ee 100644 (file)
@@ -64,6 +64,8 @@ extern EnumPropertyItem operator_return_items[];
 
 extern EnumPropertyItem brush_sculpt_tool_items[];
 
+extern EnumPropertyItem texture_type_items[];
+
 extern EnumPropertyItem unpack_method_items[];
 
 extern EnumPropertyItem object_type_items[];
index b5f3abf8b25e3acb3afed57c1067c363f5e94e19..913c387c824f62dab2a9b6d12f76ae523d69bcb3 100644 (file)
@@ -335,6 +335,7 @@ typedef struct ExtensionRNA {
 #define MainTexts Main
 #define MainActions Main
 #define MainGroups Main
+#define MainTextures Main
 
 #ifdef __cplusplus
 }
index 9dcd6eb81fabb626aba35614d0e0030413c36a83..1fdbb3f9a15db4c7eb22f6622084d5dd316e88b0 100644 (file)
@@ -191,6 +191,30 @@ PointerRNA rna_pointer_inherit_refine(PointerRNA *ptr, StructRNA *type, void *da
        return result;
 }
 
+/**/
+void RNA_pointer_recast(PointerRNA *ptr, PointerRNA *r_ptr)
+{
+#if 0 // works but this case if covered by more general code below.
+       if(RNA_struct_is_ID(ptr->type)) {
+               /* simple case */
+               RNA_id_pointer_create(ptr->id.data, r_ptr);
+       }
+       else
+#endif
+       {
+               StructRNA *base;
+               PointerRNA t_ptr;
+               *r_ptr= *ptr; /* initialize as the same incase cant recast */
+
+               for(base=ptr->type->base; base; base=base->base) {
+                       t_ptr= rna_pointer_inherit_refine(ptr, base, ptr->data);
+                       if(t_ptr.type && t_ptr.type != ptr->type) {
+                               *r_ptr= t_ptr;
+                       }
+               }
+       }
+}
+
 /* ID Properties */
 
 /* return a UI local ID prop definition for this prop */
index fdb192055b3ce8f8f93db3a00848f2bc4f7b84c0..5eadcd54774346c29c65d9a0aea6161f1496e299 100644 (file)
@@ -57,6 +57,7 @@
 #include "DNA_mesh_types.h"
 #include "DNA_object_types.h"
 #include "DNA_text_types.h"
+#include "DNA_texture_types.h"
 #include "DNA_group_types.h"
 
 #include "ED_screen.h"
@@ -66,8 +67,6 @@ Tex *rna_Main_add_texture(Main *bmain, char *name)
        return add_texture(name);
 }
 
-/* TODO: remove texture? */
-
 Image *rna_Main_add_image(Main *bmain, char *filename)
 {
        return BKE_add_image_file(filename, 0);
@@ -79,10 +78,10 @@ Camera *rna_Main_cameras_new(Main *bmain, char* name)
 }
 void rna_Main_cameras_remove(Main *bmain, ReportList *reports, struct Camera *camera)
 {
-       if(camera->id.us == 0)
+       if(ID_REAL_USERS(camera) == 0)
                free_libblock(&bmain->camera, camera);
        else
-               BKE_reportf(reports, RPT_ERROR, "Camera \"%s\" must have zero users to be removed, found %d.", camera->id.name+2, camera->id.us);
+               BKE_reportf(reports, RPT_ERROR, "Camera \"%s\" must have zero users to be removed, found %d.", camera->id.name+2, ID_REAL_USERS(camera));
 
        /* XXX python now has invalid pointer? */
 }
@@ -130,10 +129,10 @@ void rna_Main_objects_remove(Main *bmain, ReportList *reports, struct Object *ob
          # don't do this since ob is already freed!
          bpy.data.remove_object(ob)
        */
-       if(object->id.us == 0)
+       if(ID_REAL_USERS(object) == 0)
                free_libblock(&bmain->object, object);
        else
-               BKE_reportf(reports, RPT_ERROR, "Object \"%s\" must have zero users to be removed, found %d.", object->id.name+2, object->id.us);
+               BKE_reportf(reports, RPT_ERROR, "Object \"%s\" must have zero users to be removed, found %d.", object->id.name+2, ID_REAL_USERS(object));
 }
 
 struct Material *rna_Main_materials_new(Main *bmain, char* name)
@@ -142,10 +141,10 @@ struct Material *rna_Main_materials_new(Main *bmain, char* name)
 }
 void rna_Main_materials_remove(Main *bmain, ReportList *reports, struct Material *material)
 {
-       if(material->id.us == 0)
+       if(ID_REAL_USERS(material) == 0)
                free_libblock(&bmain->mat, material);
        else
-               BKE_reportf(reports, RPT_ERROR, "Material \"%s\" must have zero users to be removed, found %d.", material->id.name+2, material->id.us);
+               BKE_reportf(reports, RPT_ERROR, "Material \"%s\" must have zero users to be removed, found %d.", material->id.name+2, ID_REAL_USERS(material));
 
        /* XXX python now has invalid pointer? */
 }
@@ -158,10 +157,10 @@ Mesh *rna_Main_meshes_new(Main *bmain, char* name)
 }
 void rna_Main_meshes_remove(Main *bmain, ReportList *reports, Mesh *mesh)
 {
-       if(mesh->id.us == 0)
+       if(ID_REAL_USERS(mesh) == 0)
                free_libblock(&bmain->mesh, mesh);
        else
-               BKE_reportf(reports, RPT_ERROR, "Mesh \"%s\" must have zero users to be removed, found %d.", mesh->id.name+2, mesh->id.us);
+               BKE_reportf(reports, RPT_ERROR, "Mesh \"%s\" must have zero users to be removed, found %d.", mesh->id.name+2, ID_REAL_USERS(mesh));
 
        /* XXX python now has invalid pointer? */
 }
@@ -174,14 +173,28 @@ Lamp *rna_Main_lamps_new(Main *bmain, char* name)
 }
 void rna_Main_lamps_remove(Main *bmain, ReportList *reports, Lamp *lamp)
 {
-       if(lamp->id.us == 0)
+       if(ID_REAL_USERS(lamp) == 0)
                free_libblock(&bmain->lamp, lamp);
        else
-               BKE_reportf(reports, RPT_ERROR, "Lamp \"%s\" must have zero users to be removed, found %d.", lamp->id.name+2, lamp->id.us);
+               BKE_reportf(reports, RPT_ERROR, "Lamp \"%s\" must have zero users to be removed, found %d.", lamp->id.name+2, ID_REAL_USERS(lamp));
 
        /* XXX python now has invalid pointer? */
 }
 
+Tex *rna_Main_textures_new(Main *bmain, char* name)
+{
+       Tex *tex= add_texture(name);
+       tex->id.us--;
+       return tex;
+}
+void rna_Main_textures_remove(Main *bmain, ReportList *reports, struct Tex *tex)
+{
+       if(ID_REAL_USERS(tex) == 0)
+               free_libblock(&bmain->tex, tex);
+       else
+               BKE_reportf(reports, RPT_ERROR, "Texture \"%s\" must have zero users to be removed, found %d.", tex->id.name+2, ID_REAL_USERS(tex));
+}
+
 Group *rna_Main_groups_new(Main *bmain, char* name)
 {
        return add_group(name);
@@ -221,10 +234,10 @@ bArmature *rna_Main_armatures_new(Main *bmain, char* name)
 }
 void rna_Main_armatures_remove(Main *bmain, ReportList *reports, bArmature *arm)
 {
-       if(arm->id.us == 0)
+       if(ID_REAL_USERS(arm) == 0)
                free_libblock(&bmain->armature, arm);
        else
-               BKE_reportf(reports, RPT_ERROR, "Armature \"%s\" must have zero users to be removed, found %d.", arm->id.name+2, arm->id.us);
+               BKE_reportf(reports, RPT_ERROR, "Armature \"%s\" must have zero users to be removed, found %d.", arm->id.name+2, ID_REAL_USERS(arm));
 
        /* XXX python now has invalid pointer? */
 }
@@ -238,10 +251,10 @@ bAction *rna_Main_actions_new(Main *bmain, char* name)
 }
 void rna_Main_actions_remove(Main *bmain, ReportList *reports, bAction *act)
 {
-       if(act->id.us == 0)
+       if(ID_REAL_USERS(act) == 0)
                free_libblock(&bmain->action, act);
        else
-               BKE_reportf(reports, RPT_ERROR, "Action \"%s\" must have zero users to be removed, found %d.", act->id.name+2, act->id.us);
+               BKE_reportf(reports, RPT_ERROR, "Action \"%s\" must have zero users to be removed, found %d.", act->id.name+2, ID_REAL_USERS(act));
 
        /* XXX python now has invalid pointer? */
 }
@@ -253,12 +266,6 @@ void RNA_api_main(StructRNA *srna)
        FunctionRNA *func;
        PropertyRNA *parm;
 
-       func= RNA_def_function(srna, "add_texture", "rna_Main_add_texture");
-       RNA_def_function_ui_description(func, "Add a new texture.");
-       parm= RNA_def_string(func, "name", "Tex", 0, "", "New name for the datablock."); /* optional */
-       parm= RNA_def_pointer(func, "texture", "Texture", "", "New texture.");
-       RNA_def_function_return(func, parm);
-
        func= RNA_def_function(srna, "add_image", "rna_Main_add_image");
        RNA_def_function_ui_description(func, "Add a new image.");
        parm= RNA_def_string(func, "filename", "", 0, "", "Filename to load image from.");
@@ -457,7 +464,27 @@ void RNA_def_main_vfonts(BlenderRNA *brna, PropertyRNA *cprop)
 }
 void RNA_def_main_textures(BlenderRNA *brna, PropertyRNA *cprop)
 {
+       StructRNA *srna;
+       FunctionRNA *func;
+       PropertyRNA *parm;
+
+       RNA_def_property_srna(cprop, "MainTextures");
+       srna= RNA_def_struct(brna, "MainTextures", NULL);
+       RNA_def_struct_ui_text(srna, "Main Textures", "Collection of groups.");
 
+       func= RNA_def_function(srna, "new", "rna_Main_textures_new");
+       RNA_def_function_ui_description(func, "Add a new texture to the main database");
+       parm= RNA_def_string(func, "name", "Texture", 0, "", "New name for the datablock.");
+       RNA_def_property_flag(parm, PROP_REQUIRED);
+       /* return type */
+       parm= RNA_def_pointer(func, "texture", "Texture", "", "New texture datablock.");
+       RNA_def_function_return(func, parm);
+
+       func= RNA_def_function(srna, "remove", "rna_Main_textures_remove");
+       RNA_def_function_flag(func, FUNC_USE_REPORTS);
+       RNA_def_function_ui_description(func, "Remove a texture from the current blendfile.");
+       parm= RNA_def_pointer(func, "texture", "Texture", "", "Texture to remove.");
+       RNA_def_property_flag(parm, PROP_REQUIRED);
 }
 void RNA_def_main_brushes(BlenderRNA *brna, PropertyRNA *cprop)
 {
index 11d99b6f356cc98fd4611b08e59615eb1c901205..c352ec7973523efe6167647321fe162d9d10084e 100644 (file)
@@ -51,6 +51,25 @@ static EnumPropertyItem texture_filter_items[] = {
        {TXF_SAT, "SAT", 0, "SAT (4x mem)", ""},
        {0, NULL, 0, NULL, NULL}};
 
+EnumPropertyItem texture_type_items[] = {
+       {0, "NONE", 0, "None", ""},
+       {TEX_BLEND, "BLEND", ICON_TEXTURE, "Blend", ""},
+       {TEX_CLOUDS, "CLOUDS", ICON_TEXTURE, "Clouds", ""},
+       {TEX_DISTNOISE, "DISTORTED_NOISE", ICON_TEXTURE, "Distorted Noise", ""},
+       {TEX_ENVMAP, "ENVIRONMENT_MAP", ICON_IMAGE_DATA, "Environment Map", ""},
+       {TEX_IMAGE, "IMAGE", ICON_IMAGE_DATA, "Image or Movie", ""},
+       {TEX_MAGIC, "MAGIC", ICON_TEXTURE, "Magic", ""},
+       {TEX_MARBLE, "MARBLE", ICON_TEXTURE, "Marble", ""},
+       {TEX_MUSGRAVE, "MUSGRAVE", ICON_TEXTURE, "Musgrave", ""},
+       {TEX_NOISE, "NOISE", ICON_TEXTURE, "Noise", ""},
+       {TEX_PLUGIN, "PLUGIN", ICON_PLUGIN, "Plugin", ""},
+       {TEX_POINTDENSITY, "POINT_DENSITY", ICON_TEXTURE, "Point Density", ""},
+       {TEX_STUCCI, "STUCCI", ICON_TEXTURE, "Stucci", ""},
+       {TEX_VORONOI, "VORONOI", ICON_TEXTURE, "Voronoi", ""},
+       {TEX_VOXELDATA, "VOXEL_DATA", ICON_TEXTURE, "Voxel Data", ""},
+       {TEX_WOOD, "WOOD", ICON_TEXTURE, "Wood", ""},
+       {0, NULL, 0, NULL, NULL}};
+
 #ifdef RNA_RUNTIME
 
 #include "MEM_guardedalloc.h"
@@ -1791,25 +1810,6 @@ static void rna_def_texture(BlenderRNA *brna)
        StructRNA *srna;
        PropertyRNA *prop;
 
-       static EnumPropertyItem prop_type_items[] = {
-               {0, "NONE", 0, "None", ""},
-               {TEX_BLEND, "BLEND", ICON_TEXTURE, "Blend", ""},
-               {TEX_CLOUDS, "CLOUDS", ICON_TEXTURE, "Clouds", ""},
-               {TEX_DISTNOISE, "DISTORTED_NOISE", ICON_TEXTURE, "Distorted Noise", ""},
-               {TEX_ENVMAP, "ENVIRONMENT_MAP", ICON_IMAGE_DATA, "Environment Map", ""},
-               {TEX_IMAGE, "IMAGE", ICON_IMAGE_DATA, "Image or Movie", ""},
-               {TEX_MAGIC, "MAGIC", ICON_TEXTURE, "Magic", ""},
-               {TEX_MARBLE, "MARBLE", ICON_TEXTURE, "Marble", ""},
-               {TEX_MUSGRAVE, "MUSGRAVE", ICON_TEXTURE, "Musgrave", ""},
-               {TEX_NOISE, "NOISE", ICON_TEXTURE, "Noise", ""},
-               {TEX_PLUGIN, "PLUGIN", ICON_PLUGIN, "Plugin", ""},
-               {TEX_POINTDENSITY, "POINT_DENSITY", ICON_TEXTURE, "Point Density", ""},
-               {TEX_STUCCI, "STUCCI", ICON_TEXTURE, "Stucci", ""},
-               {TEX_VORONOI, "VORONOI", ICON_TEXTURE, "Voronoi", ""},
-               {TEX_VOXELDATA, "VOXEL_DATA", ICON_TEXTURE, "Voxel Data", ""},
-               {TEX_WOOD, "WOOD", ICON_TEXTURE, "Wood", ""},
-               {0, NULL, 0, NULL, NULL}};
-
        srna= RNA_def_struct(brna, "Texture", "ID");
        RNA_def_struct_sdna(srna, "Tex");
        RNA_def_struct_ui_text(srna, "Texture", "Texture datablock used by materials, lamps, worlds and brushes.");
@@ -1819,7 +1819,7 @@ static void rna_def_texture(BlenderRNA *brna)
        prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
        //RNA_def_property_clear_flag(prop, PROP_EDITABLE);
        RNA_def_property_enum_sdna(prop, NULL, "type");
-       RNA_def_property_enum_items(prop, prop_type_items);
+       RNA_def_property_enum_items(prop, texture_type_items);
        RNA_def_property_enum_funcs(prop, NULL, "rna_Texture_type_set", NULL);
        RNA_def_property_ui_text(prop, "Type", "");
        RNA_def_property_update(prop, 0, "rna_Texture_update");
index a4f61b7292d420c4fab3a3bff7456f13ff91e953..bee6c4f70da4338765ba29d42c7fa9735596b772 100644 (file)
@@ -1713,6 +1713,13 @@ static PyObject *pyrna_struct_path_to_id(BPy_StructRNA *self, PyObject *args)
        return ret;
 }
 
+static PyObject *pyrna_struct_recast_type(BPy_StructRNA *self, PyObject *args)
+{
+       PointerRNA r_ptr;
+       RNA_pointer_recast(&self->ptr, &r_ptr);
+       return pyrna_struct_CreatePyObject(&r_ptr);
+}
+
 static PyObject *pyrna_prop_path_to_id(BPy_PropertyRNA *self)
 {
        char *path;
@@ -2537,6 +2544,7 @@ static struct PyMethodDef pyrna_struct_methods[] = {
        {"is_property_hidden", (PyCFunction)pyrna_struct_is_property_hidden, METH_VARARGS, NULL},
        {"path_resolve", (PyCFunction)pyrna_struct_path_resolve, METH_O, NULL},
        {"path_to_id", (PyCFunction)pyrna_struct_path_to_id, METH_VARARGS, NULL},
+       {"recast_type", (PyCFunction)pyrna_struct_recast_type, METH_NOARGS, NULL},
        {"__dir__", (PyCFunction)pyrna_struct_dir, METH_NOARGS, NULL},
        {NULL, NULL, 0, NULL}
 };