bugfix [#20639] BF25_SVN_25888 and below - OBJ and 3DS import fails

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()
This commit is contained in:
2010-01-17 20:06:34 +00:00
parent 55756719fb
commit c7dfa96aea
12 changed files with 116 additions and 49 deletions

View 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):

View 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')

View 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);

View 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++;

View 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

View 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;

View 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[];

View File

@@ -335,6 +335,7 @@ typedef struct ExtensionRNA {
#define MainTexts Main
#define MainActions Main
#define MainGroups Main
#define MainTextures Main
#ifdef __cplusplus
}

View 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 */

View 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)
{

View 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");

View 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}
};