diff options
38 files changed, 419 insertions, 112 deletions
diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h index aff3fb08df6..bb3ad0efb63 100644 --- a/source/blender/blenkernel/BKE_brush.h +++ b/source/blender/blenkernel/BKE_brush.h @@ -40,6 +40,7 @@ void BKE_brush_system_init(void); void BKE_brush_system_exit(void); /* datablock functions */ +void BKE_brush_init(struct Brush *brush); struct Brush *BKE_brush_add(struct Main *bmain, const char *name, short ob_mode); struct Brush *BKE_brush_first_search(struct Main *bmain, short ob_mode); struct Brush *BKE_brush_copy(struct Brush *brush); diff --git a/source/blender/blenkernel/BKE_camera.h b/source/blender/blenkernel/BKE_camera.h index aacb7a4066b..118153a9163 100644 --- a/source/blender/blenkernel/BKE_camera.h +++ b/source/blender/blenkernel/BKE_camera.h @@ -50,6 +50,7 @@ struct GPUFXSettings; /* Camera Datablock */ +void BKE_camera_init(struct Camera *cam); void *BKE_camera_add(struct Main *bmain, const char *name); struct Camera *BKE_camera_copy(struct Camera *cam); void BKE_camera_make_local(struct Camera *cam); diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index a03dd287146..061270b8b41 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -69,6 +69,7 @@ typedef struct CurveCache { void BKE_curve_unlink(struct Curve *cu); void BKE_curve_free(struct Curve *cu); void BKE_curve_editfont_free(struct Curve *cu); +void BKE_curve_init(struct Curve *cu); struct Curve *BKE_curve_add(struct Main *bmain, const char *name, int type); struct Curve *BKE_curve_copy(struct Curve *cu); void BKE_curve_make_local(struct Curve *cu); diff --git a/source/blender/blenkernel/BKE_font.h b/source/blender/blenkernel/BKE_font.h index f20c166aa6d..5dcc6f8d981 100644 --- a/source/blender/blenkernel/BKE_font.h +++ b/source/blender/blenkernel/BKE_font.h @@ -79,6 +79,7 @@ void BKE_vfont_builtin_register(void *mem, int size); void BKE_vfont_free_data(struct VFont *vfont); void BKE_vfont_free(struct VFont *sc); +void BKE_vfont_init(struct VFont *vfont); struct VFont *BKE_vfont_builtin_get(void); struct VFont *BKE_vfont_load(struct Main *bmain, const char *filepath); struct VFont *BKE_vfont_load_exists_ex(struct Main *bmain, const char *filepath, bool *r_exists); diff --git a/source/blender/blenkernel/BKE_lamp.h b/source/blender/blenkernel/BKE_lamp.h index fb2c4da91ea..d830c19651f 100644 --- a/source/blender/blenkernel/BKE_lamp.h +++ b/source/blender/blenkernel/BKE_lamp.h @@ -42,6 +42,7 @@ struct Lamp; struct Main; struct Scene; +void BKE_lamp_init(struct Lamp *la); struct Lamp *BKE_lamp_add(struct Main *bmain, const char *name) ATTR_WARN_UNUSED_RESULT; struct Lamp *BKE_lamp_copy(struct Lamp *la) ATTR_WARN_UNUSED_RESULT; struct Lamp *localize_lamp(struct Lamp *la) ATTR_WARN_UNUSED_RESULT; diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h index 677d8e34229..828a40de1c9 100644 --- a/source/blender/blenkernel/BKE_lattice.h +++ b/source/blender/blenkernel/BKE_lattice.h @@ -45,6 +45,7 @@ struct BPoint; struct MDeformVert; void BKE_lattice_resize(struct Lattice *lt, int u, int v, int w, struct Object *ltOb); +void BKE_lattice_init(struct Lattice *lt); struct Lattice *BKE_lattice_add(struct Main *bmain, const char *name); struct Lattice *BKE_lattice_copy(struct Lattice *lt); void BKE_lattice_free(struct Lattice *lt); diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h index 4fab910b7ee..f46ae5617ac 100644 --- a/source/blender/blenkernel/BKE_library.h +++ b/source/blender/blenkernel/BKE_library.h @@ -49,7 +49,9 @@ struct bContext; struct PointerRNA; struct PropertyRNA; +void *BKE_libblock_alloc_notest(short type); void *BKE_libblock_alloc(struct Main *bmain, short type, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +void BKE_libblock_init_empty(struct ID *id); void *BKE_libblock_copy_ex(struct Main *bmain, struct ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); void *BKE_libblock_copy_nolib(struct ID *id, const bool do_action) ATTR_NONNULL(); void *BKE_libblock_copy(struct ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); diff --git a/source/blender/blenkernel/BKE_linestyle.h b/source/blender/blenkernel/BKE_linestyle.h index e77b4f5e8fe..e3eead4102c 100644 --- a/source/blender/blenkernel/BKE_linestyle.h +++ b/source/blender/blenkernel/BKE_linestyle.h @@ -49,6 +49,7 @@ struct Object; struct ColorBand; struct bContext; +void BKE_linestyle_init(struct FreestyleLineStyle *linestyle); FreestyleLineStyle *BKE_linestyle_new(struct Main *bmain, const char *name); void BKE_linestyle_free(FreestyleLineStyle *linestyle); FreestyleLineStyle *BKE_linestyle_copy(struct Main *bmain, FreestyleLineStyle *linestyle); diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h index a3c61f44ff2..d32d679e7ed 100644 --- a/source/blender/blenkernel/BKE_material.h +++ b/source/blender/blenkernel/BKE_material.h @@ -49,7 +49,7 @@ void BKE_material_free(struct Material *sc); void BKE_material_free_ex(struct Material *ma, bool do_id_user); void test_object_materials(struct Main *bmain, struct ID *id); void BKE_material_resize_object(struct Object *ob, const short totcol, bool do_id_user); -void init_material(struct Material *ma); +void BKE_material_init(struct Material *ma); void BKE_material_remap_object(struct Object *ob, const unsigned int *remap); struct Material *BKE_material_add(struct Main *bmain, const char *name); struct Material *BKE_material_copy(struct Material *ma); diff --git a/source/blender/blenkernel/BKE_mball.h b/source/blender/blenkernel/BKE_mball.h index 62cd50099fd..0574b88bef3 100644 --- a/source/blender/blenkernel/BKE_mball.h +++ b/source/blender/blenkernel/BKE_mball.h @@ -40,6 +40,7 @@ struct MetaElem; void BKE_mball_unlink(struct MetaBall *mb); void BKE_mball_free(struct MetaBall *mb); +void BKE_mball_init(struct MetaBall *mb); struct MetaBall *BKE_mball_add(struct Main *bmain, const char *name); struct MetaBall *BKE_mball_copy(struct MetaBall *mb); diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 5bd8931ee2e..f35613f8bf7 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -82,6 +82,7 @@ int BKE_mesh_edge_other_vert(const struct MEdge *e, int v); void BKE_mesh_unlink(struct Mesh *me); void BKE_mesh_free(struct Mesh *me, int unlink); +void BKE_mesh_init(struct Mesh *me); struct Mesh *BKE_mesh_add(struct Main *bmain, const char *name); struct Mesh *BKE_mesh_copy_ex(struct Main *bmain, struct Mesh *me); struct Mesh *BKE_mesh_copy(struct Mesh *me); diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index b97bf203a7c..88e54d0ff2c 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -337,6 +337,7 @@ struct GHashIterator *ntreeTypeGetIterator(void); void ntreeSetTypes(const struct bContext *C, struct bNodeTree *ntree); +void ntreeInitDefault(struct bNodeTree *ntree); struct bNodeTree *ntreeAddTree(struct Main *bmain, const char *name, const char *idname); /* copy/free funcs, need to manage ID users */ diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index f3a1be24af6..45d14a35539 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -85,6 +85,7 @@ bool BKE_object_is_in_editmode(struct Object *ob); bool BKE_object_is_in_editmode_vgroup(struct Object *ob); bool BKE_object_is_in_wpaint_select_vert(struct Object *ob); +void BKE_object_init(struct Object *ob); struct Object *BKE_object_add_only_object( struct Main *bmain, int type, const char *name) diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 027bdbbbe58..aa698317e33 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -67,6 +67,7 @@ void free_avicodecdata(struct AviCodecData *acd); void free_qtcodecdata(struct QuicktimeCodecData *acd); void BKE_scene_free(struct Scene *sce); +void BKE_scene_init(struct Scene *sce); struct Scene *BKE_scene_add(struct Main *bmain, const char *name); /* base functions */ diff --git a/source/blender/blenkernel/BKE_speaker.h b/source/blender/blenkernel/BKE_speaker.h index 5d93b9844ab..5f30df1d6e3 100644 --- a/source/blender/blenkernel/BKE_speaker.h +++ b/source/blender/blenkernel/BKE_speaker.h @@ -29,7 +29,9 @@ */ struct Main; +struct Speaker; +void BKE_speaker_init(struct Speaker *spk); void *BKE_speaker_add(struct Main *bmain, const char *name); struct Speaker *BKE_speaker_copy(struct Speaker *spk); void BKE_speaker_make_local(struct Speaker *spk); diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h index a5a59d14c92..50e4fa4c41d 100644 --- a/source/blender/blenkernel/BKE_text.h +++ b/source/blender/blenkernel/BKE_text.h @@ -44,6 +44,7 @@ struct TextLine; void BKE_text_free (struct Text *text); void txt_set_undostate (int u); int txt_get_undostate (void); +void BKE_text_init(struct Text *ta); struct Text *BKE_text_add (struct Main *bmain, const char *name); int txt_extended_ascii_as_utf8(char **str); bool BKE_text_reload(struct Text *text); diff --git a/source/blender/blenkernel/BKE_world.h b/source/blender/blenkernel/BKE_world.h index 7f4ba6c615e..8d7ab230919 100644 --- a/source/blender/blenkernel/BKE_world.h +++ b/source/blender/blenkernel/BKE_world.h @@ -38,6 +38,7 @@ struct World; void BKE_world_free(struct World *sc); void BKE_world_free_ex(struct World *sc, bool do_id_user); +void BKE_world_init(struct World *wrld); struct World *add_world(struct Main *bmian, const char *name); struct World *BKE_world_copy(struct World *wrld); struct World *localize_world(struct World *wrld); diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index e0ffd830804..c2a66adbf92 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -131,11 +131,9 @@ static void brush_defaults(Brush *brush) /* Datablock add/copy/free/make_local */ -Brush *BKE_brush_add(Main *bmain, const char *name, short ob_mode) +void BKE_brush_init(Brush *brush) { - Brush *brush; - - brush = BKE_libblock_alloc(bmain, ID_BR, name); + BLI_assert(MEMCMP_STRUCT_OFS_IS_ZERO(brush, id)); /* enable fake user by default */ brush->id.flag |= LIB_FAKEUSER; @@ -143,10 +141,20 @@ Brush *BKE_brush_add(Main *bmain, const char *name, short ob_mode) brush_defaults(brush); brush->sculpt_tool = SCULPT_TOOL_DRAW; /* sculpting defaults to the draw tool for new brushes */ - brush->ob_mode = ob_mode; /* the default alpha falloff curve */ BKE_brush_curve_preset(brush, CURVE_PRESET_SMOOTH); +} + +Brush *BKE_brush_add(Main *bmain, const char *name, short ob_mode) +{ + Brush *brush; + + brush = BKE_libblock_alloc(bmain, ID_BR, name); + + BKE_brush_init(brush); + + brush->ob_mode = ob_mode; return brush; } diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c index 7e043df2808..46b74c58965 100644 --- a/source/blender/blenkernel/intern/camera.c +++ b/source/blender/blenkernel/intern/camera.c @@ -57,11 +57,9 @@ /****************************** Camera Datablock *****************************/ -void *BKE_camera_add(Main *bmain, const char *name) +void BKE_camera_init(Camera *cam) { - Camera *cam; - - cam = BKE_libblock_alloc(bmain, ID_CA, name); + BLI_assert(MEMCMP_STRUCT_OFS_IS_ZERO(cam, id)); cam->lens = 35.0f; cam->sensor_x = DEFAULT_SENSOR_WIDTH; @@ -78,6 +76,15 @@ void *BKE_camera_add(Main *bmain, const char *name) /* stereoscopy 3d */ cam->stereo.interocular_distance = 0.065f; cam->stereo.convergence_distance = 30.f * 0.065f; +} + +void *BKE_camera_add(Main *bmain, const char *name) +{ + Camera *cam; + + cam = BKE_libblock_alloc(bmain, ID_CA, name); + + BKE_camera_init(cam); return cam; } diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 8d7d62be7e4..3e0bdbe31af 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -161,15 +161,14 @@ void BKE_curve_free(Curve *cu) MEM_freeN(cu->tb); } -Curve *BKE_curve_add(Main *bmain, const char *name, int type) +void BKE_curve_init(Curve *cu) { - Curve *cu; + /* BLI_assert(MEMCMP_STRUCT_OFS_IS_ZERO(cu, id)); */ /* cu->type is already initialized... */ - cu = BKE_libblock_alloc(bmain, ID_CU, name); copy_v3_fl(cu->size, 1.0f); cu->flag = CU_FRONT | CU_BACK | CU_DEFORM_BOUNDS_OFF | CU_PATH_RADIUS; cu->pathlen = 100; - cu->resolu = cu->resolv = (type == OB_SURF) ? 4 : 12; + cu->resolu = cu->resolv = (cu->type == OB_SURF) ? 4 : 12; cu->width = 1.0; cu->wordspace = 1.0; cu->spacing = cu->linedist = 1.0; @@ -179,7 +178,6 @@ Curve *BKE_curve_add(Main *bmain, const char *name, int type) cu->smallcaps_scale = 0.75f; /* XXX: this one seems to be the best one in most cases, at least for curve deform... */ cu->twist_mode = CU_TWIST_MINIMUM; - cu->type = type; cu->bevfac1 = 0.0f; cu->bevfac2 = 1.0f; cu->bevfac1_mapping = CU_BEVFAC_MAP_RESOLU; @@ -187,7 +185,7 @@ Curve *BKE_curve_add(Main *bmain, const char *name, int type) cu->bb = BKE_boundbox_alloc_unit(); - if (type == OB_FONT) { + if (cu->type == OB_FONT) { cu->vfont = cu->vfontb = cu->vfonti = cu->vfontbi = BKE_vfont_builtin_get(); cu->vfont->id.us += 4; cu->str = MEM_mallocN(12, "str"); @@ -198,6 +196,16 @@ Curve *BKE_curve_add(Main *bmain, const char *name, int type) cu->tb = MEM_callocN(MAXTEXTBOX * sizeof(TextBox), "textbox"); cu->tb[0].w = cu->tb[0].h = 0.0; } +} + +Curve *BKE_curve_add(Main *bmain, const char *name, int type) +{ + Curve *cu; + + cu = BKE_libblock_alloc(bmain, ID_CU, name); + cu->type = type; + + BKE_curve_init(cu); return cu; } diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index e3ebb7f908c..b12e16d9502 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -203,6 +203,26 @@ static VFontData *vfont_get_data(Main *bmain, VFont *vfont) return vfont->data; } +/* Bad naming actually in this case... */ +void BKE_vfont_init(VFont *vfont) +{ + PackedFile *pf = get_builtin_packedfile(); + + if (pf) { + VFontData *vfd; + + vfd = BLI_vfontdata_from_freetypefont(pf); + if (vfd) { + vfont->data = vfd; + + BLI_strncpy(vfont->name, FO_BUILTIN_NAME, sizeof(vfont->name)); + } + + /* Free the packed file */ + freePackedFile(pf); + } +} + VFont *BKE_vfont_load(Main *bmain, const char *filepath) { char filename[FILE_MAXFILE]; diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c index 44e35c645de..8e350896eb8 100644 --- a/source/blender/blenkernel/intern/lamp.c +++ b/source/blender/blenkernel/intern/lamp.c @@ -53,12 +53,10 @@ #include "BKE_main.h" #include "BKE_node.h" -Lamp *BKE_lamp_add(Main *bmain, const char *name) +void BKE_lamp_init(Lamp *la) { - Lamp *la; - - la = BKE_libblock_alloc(bmain, ID_LA, name); - + BLI_assert(MEMCMP_STRUCT_OFS_IS_ZERO(la, id)); + la->r = la->g = la->b = la->k = 1.0f; la->haint = la->energy = 1.0f; la->dist = 25.0f; @@ -100,6 +98,16 @@ Lamp *BKE_lamp_add(Main *bmain, const char *name) la->shadow_frustum_size = 10.0f; curvemapping_initialize(la->curfalloff); +} + +Lamp *BKE_lamp_add(Main *bmain, const char *name) +{ + Lamp *la; + + la = BKE_libblock_alloc(bmain, ID_LA, name); + + BKE_lamp_init(la); + return la; } diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 009e1d20328..0e5228a6db4 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -251,12 +251,10 @@ void BKE_lattice_resize(Lattice *lt, int uNew, int vNew, int wNew, Object *ltOb) MEM_freeN(vertexCos); } -Lattice *BKE_lattice_add(Main *bmain, const char *name) +void BKE_lattice_init(Lattice *lt) { - Lattice *lt; - - lt = BKE_libblock_alloc(bmain, ID_LT, name); - + BLI_assert(MEMCMP_STRUCT_OFS_IS_ZERO(lt, id)); + lt->flag = LT_GRID; lt->typeu = lt->typev = lt->typew = KEY_BSPLINE; @@ -264,7 +262,16 @@ Lattice *BKE_lattice_add(Main *bmain, const char *name) lt->def = MEM_callocN(sizeof(BPoint), "lattvert"); /* temporary */ BKE_lattice_resize(lt, 2, 2, 2, NULL); /* creates a uniform lattice */ lt->actbp = LT_ACTBP_NONE; - +} + +Lattice *BKE_lattice_add(Main *bmain, const char *name) +{ + Lattice *lt; + + lt = BKE_libblock_alloc(bmain, ID_LT, name); + + BKE_lattice_init(lt); + return lt; } diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index d6b2a3cea29..f8f92825479 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -59,6 +59,7 @@ #include "DNA_movieclip_types.h" #include "DNA_mask_types.h" #include "DNA_node_types.h" +#include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_speaker_types.h" @@ -648,7 +649,7 @@ int set_listbasepointers(Main *main, ListBase **lb) * Allocates and returns memory of the right size for the specified block type, * initialized to zero. */ -static ID *alloc_libblock_notest(short type) +void *BKE_libblock_alloc_notest(short type) { ID *id = NULL; @@ -770,7 +771,7 @@ void *BKE_libblock_alloc(Main *bmain, short type, const char *name) ID *id = NULL; ListBase *lb = which_libbase(bmain, type); - id = alloc_libblock_notest(type); + id = BKE_libblock_alloc_notest(type); if (id) { BKE_main_lock(bmain); BLI_addtail(lb, id); @@ -785,6 +786,121 @@ void *BKE_libblock_alloc(Main *bmain, short type, const char *name) return id; } +/** + * Initialize an ID of given type, such that it has valid 'empty' data. + * ID is assumed to be just calloc'ed. + */ +void BKE_libblock_init_empty(ID *id) +{ + /* Note that only ID types that are not valid when filled of zero should have a callback here. */ + switch (GS(id->name)) { + case ID_SCE: + BKE_scene_init((Scene *)id); + break; + case ID_LI: + /* Nothing to do. */ + break; + case ID_OB: + { + Object *ob = (Object *)id; + ob->type = OB_EMPTY; + BKE_object_init(ob); + break; + } + case ID_ME: + BKE_mesh_init((Mesh *)id); + break; + case ID_CU: + BKE_curve_init((Curve *)id); + break; + case ID_MB: + BKE_mball_init((MetaBall *)id); + break; + case ID_MA: + BKE_material_init((Material *)id); + break; + case ID_TE: + BKE_texture_default((Tex *)id); + break; + case ID_IM: + /* Image is a bit complicated, for now assume NULLified im is OK. */ + break; + case ID_LT: + BKE_lattice_init((Lattice *)id); + break; + case ID_LA: + BKE_lamp_init((Lamp *)id); + break; + case ID_SPK: + BKE_speaker_init((Speaker *)id); + break; + case ID_CA: + BKE_camera_init((Camera *)id); + break; + case ID_IP: + /* Should not be needed - animation from lib pre-2.5 is broken anyway. */ + BLI_assert(0); + break; + case ID_KE: + /* Shapekeys are a complex topic too - they depend on their 'user' data type... + * They are not linkable, though, so it should never reach here anyway. */ + BLI_assert(0); + break; + case ID_WO: + BKE_world_init((World *)id); + break; + case ID_SCR: + /* Nothing to do. */ + break; + case ID_VF: + BKE_vfont_init((VFont *)id); + break; + case ID_TXT: + BKE_text_init((Text *)id); + break; + case ID_SCRIPT: + BLI_assert(0); + break; + case ID_SO: + /* Another fuzzy case, think NULLified content is OK here... */ + break; + case ID_GR: + /* Nothing to do. */ + break; + case ID_AR: + /* Nothing to do. */ + break; + case ID_AC: + /* Nothing to do. */ + break; + case ID_NT: + ntreeInitDefault((bNodeTree *)id); + break; + case ID_BR: + BKE_brush_init((Brush *)id); + break; + case ID_PA: + /* Nothing to do. */ + break; + case ID_PC: + /* Nothing to do. */ + break; + case ID_WM: + /* We should never reach this. */ + BLI_assert(0); + break; + case ID_GD: + /* Nothing to do. */ + break; + case ID_MSK: + /* Nothing to do. */ + break; + case ID_LS: + BKE_linestyle_init((FreestyleLineStyle *)id); + break; + } +} + /* by spec, animdata is first item after ID */ /* and, trust that BKE_animdata_from_id() will only find AnimData for valid ID-types */ static void id_copy_animdata(ID *id, const bool do_action) @@ -838,7 +954,7 @@ void *BKE_libblock_copy_nolib(ID *id, const bool do_action) ID *idn; size_t idn_len; - idn = alloc_libblock_notest(GS(id->name)); + idn = BKE_libblock_alloc_notest(GS(id->name)); assert(idn != NULL); BLI_strncpy(idn->name, id->name, sizeof(idn->name)); @@ -1720,7 +1836,7 @@ void rename_id(ID *id, const char *name) */ void name_uiprefix_id(char *name, const ID *id) { - name[0] = id->lib ? 'L' : ' '; + name[0] = id->lib ? (ID_MISSING(id) ? 'M' : 'L') : ' '; name[1] = (id->flag & LIB_FAKEUSER) ? 'F' : ((id->us == 0) ? '0' : ' '); name[2] = ' '; diff --git a/source/blender/blenkernel/intern/linestyle.c b/source/blender/blenkernel/intern/linestyle.c index ac2c4e35dce..93d2b549fee 100644 --- a/source/blender/blenkernel/intern/linestyle.c +++ b/source/blender/blenkernel/intern/linestyle.c @@ -80,8 +80,10 @@ static const char *modifier_name[LS_MODIFIER_NUM] = { "3D Curvature", }; -static void default_linestyle_settings(FreestyleLineStyle *linestyle) +void BKE_linestyle_init(FreestyleLineStyle *linestyle) { + BLI_assert(MEMCMP_STRUCT_OFS_IS_ZERO(linestyle, id)); + linestyle->panel = LS_PANEL_STROKES; linestyle->r = linestyle->g = linestyle->b = 0.0f; linestyle->alpha = 1.0f; @@ -118,7 +120,7 @@ FreestyleLineStyle *BKE_linestyle_new(struct Main *bmain, const char *name) linestyle = (FreestyleLineStyle *)BKE_libblock_alloc(bmain, ID_LS, name); - default_linestyle_settings(linestyle); + BKE_linestyle_init(linestyle); return linestyle; } diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 3e7e98b4a1d..a69b5fd87b5 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -78,7 +78,7 @@ Material defmaterial; /* called on startup, creator.c */ void init_def_material(void) { - init_material(&defmaterial); + BKE_material_init(&defmaterial); } /* not material itself */ @@ -122,8 +122,10 @@ void BKE_material_free_ex(Material *ma, bool do_id_user) GPU_material_free(&ma->gpumaterial); } -void init_material(Material *ma) +void BKE_material_init(Material *ma) { + BLI_assert(MEMCMP_STRUCT_OFS_IS_ZERO(ma, id)); + ma->r = ma->g = ma->b = ma->ref = 0.8; ma->specr = ma->specg = ma->specb = 1.0; ma->mirr = ma->mirg = ma->mirb = 1.0; @@ -221,7 +223,7 @@ Material *BKE_material_add(Main *bmain, const char *name) ma = BKE_libblock_alloc(bmain, ID_MA, name); - init_material(ma); + BKE_material_init(ma); return ma; } diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index c09cd1aabdc..bd9fd331584 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -91,19 +91,26 @@ void BKE_mball_free(MetaBall *mb) if (mb->disp.first) BKE_displist_free(&mb->disp); } -MetaBall *BKE_mball_add(Main *bmain, const char *name) +void BKE_mball_init(MetaBall *mb) { - MetaBall *mb; - - mb = BKE_libblock_alloc(bmain, ID_MB, name); - + BLI_assert(MEMCMP_STRUCT_OFS_IS_ZERO(mb, id)); + mb->size[0] = mb->size[1] = mb->size[2] = 1.0; mb->texflag = MB_AUTOSPACE; mb->wiresize = 0.4f; mb->rendersize = 0.2f; mb->thresh = 0.6f; - +} + +MetaBall *BKE_mball_add(Main *bmain, const char *name) +{ + MetaBall *mb; + + mb = BKE_libblock_alloc(bmain, ID_MB, name); + + BKE_mball_init(mb); + return mb; } diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index b948ed56c56..318040db2be 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -490,12 +490,10 @@ static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata) mesh->totface = 0; } -Mesh *BKE_mesh_add(Main *bmain, const char *name) +void BKE_mesh_init(Mesh *me) { - Mesh *me; - - me = BKE_libblock_alloc(bmain, ID_ME, name); - + BLI_assert(MEMCMP_STRUCT_OFS_IS_ZERO(me, id)); + me->size[0] = me->size[1] = me->size[2] = 1.0; me->smoothresh = 30; me->texflag = ME_AUTOSPACE; @@ -511,6 +509,15 @@ Mesh *BKE_mesh_add(Main *bmain, const char *name) CustomData_reset(&me->fdata); CustomData_reset(&me->pdata); CustomData_reset(&me->ldata); +} + +Mesh *BKE_mesh_add(Main *bmain, const char *name) +{ + Mesh *me; + + me = BKE_libblock_alloc(bmain, ID_ME, name); + + BKE_mesh_init(me); return me; } diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index c656931d18b..d3460dcb481 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1151,6 +1151,11 @@ void nodeDetachNode(struct bNode *node) } } +void ntreeInitDefault(bNodeTree *ntree) +{ + ntree_set_typeinfo(ntree, NULL); +} + bNodeTree *ntreeAddTree(Main *bmain, const char *name, const char *idname) { bNodeTree *ntree; diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index e5f826f670d..ffb614fdf11 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -972,19 +972,10 @@ void *BKE_object_obdata_add_from_type(Main *bmain, int type, const char *name) } } -/* more general add: creates minimum required data, but without vertices etc. */ -Object *BKE_object_add_only_object(Main *bmain, int type, const char *name) +void BKE_object_init(Object *ob) { - Object *ob; + /* BLI_assert(MEMCMP_STRUCT_OFS_IS_ZERO(ob, id)); */ /* ob->type is already initialized... */ - if (!name) - name = get_obdata_defname(type); - - ob = BKE_libblock_alloc(bmain, ID_OB, name); - - /* default object vars */ - ob->type = type; - ob->col[0] = ob->col[1] = ob->col[2] = 1.0; ob->col[3] = 1.0; @@ -1012,7 +1003,7 @@ Object *BKE_object_add_only_object(Main *bmain, int type, const char *name) ob->empty_drawtype = OB_PLAINAXES; ob->empty_drawsize = 1.0; - if (ELEM(type, OB_LAMP, OB_CAMERA, OB_SPEAKER)) { + if (ELEM(ob->type, OB_LAMP, OB_CAMERA, OB_SPEAKER)) { ob->trackflag = OB_NEGZ; ob->upflag = OB_POSY; } @@ -1053,6 +1044,22 @@ Object *BKE_object_add_only_object(Main *bmain, int type, const char *name) /* Animation Visualization defaults */ animviz_settings_init(&ob->avs); +} + +/* more general add: creates minimum required data, but without vertices etc. */ +Object *BKE_object_add_only_object(Main *bmain, int type, const char *name) +{ + Object *ob; + + if (!name) + name = get_obdata_defname(type); + + ob = BKE_libblock_alloc(bmain, ID_OB, name); + + /* default object vars */ + ob->type = type; + + BKE_object_init(ob); return ob; } diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 1ccc213006a..cc656775c14 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -464,15 +464,15 @@ void BKE_scene_free(Scene *sce) BKE_previewimg_free(&sce->preview); } -Scene *BKE_scene_add(Main *bmain, const char *name) +void BKE_scene_init(Scene *sce) { - Scene *sce; ParticleEditSettings *pset; int a; const char *colorspace_name; SceneRenderView *srv; - sce = BKE_libblock_alloc(bmain, ID_SCE, name); + BLI_assert(MEMCMP_STRUCT_OFS_IS_ZERO(sce, id)); + sce->lay = sce->layact = 1; sce->r.mode = R_GAMMA | R_OSA | R_SHADOW | R_SSS | R_ENVMAP | R_RAYTRACE; @@ -743,6 +743,15 @@ Scene *BKE_scene_add(Main *bmain, const char *name) copy_v2_fl2(sce->safe_areas.action_center, 15.0f / 100.0f, 5.0f / 100.0f); sce->preview = NULL; +} + +Scene *BKE_scene_add(Main *bmain, const char *name) +{ + Scene *sce; + + sce = BKE_libblock_alloc(bmain, ID_SCE, name); + + BKE_scene_init(sce); return sce; } diff --git a/source/blender/blenkernel/intern/speaker.c b/source/blender/blenkernel/intern/speaker.c index 7a800555144..30296c7813c 100644 --- a/source/blender/blenkernel/intern/speaker.c +++ b/source/blender/blenkernel/intern/speaker.c @@ -37,11 +37,9 @@ #include "BKE_main.h" #include "BKE_speaker.h" -void *BKE_speaker_add(Main *bmain, const char *name) +void BKE_speaker_init(Speaker *spk) { - Speaker *spk; - - spk = BKE_libblock_alloc(bmain, ID_SPK, name); + BLI_assert(MEMCMP_STRUCT_OFS_IS_ZERO(spk, id)); spk->attenuation = 1.0f; spk->cone_angle_inner = 360.0f; @@ -55,6 +53,15 @@ void *BKE_speaker_add(Main *bmain, const char *name) spk->volume = 1.0f; spk->volume_max = 1.0f; spk->volume_min = 0.0f; +} + +void *BKE_speaker_add(Main *bmain, const char *name) +{ + Speaker *spk; + + spk = BKE_libblock_alloc(bmain, ID_SPK, name); + + BKE_speaker_init(spk); return spk; } diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 77d6043d6f3..6e41ed3f9a6 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -171,14 +171,12 @@ void BKE_text_free(Text *text) #endif } -Text *BKE_text_add(Main *bmain, const char *name) +void BKE_text_init(Text *ta) { - Text *ta; TextLine *tmp; - - ta = BKE_libblock_alloc(bmain, ID_TXT, name); - ta->id.us = 1; - + + BLI_assert(MEMCMP_STRUCT_OFS_IS_ZERO(ta, id)); + ta->name = NULL; init_undo_text(ta); @@ -206,6 +204,15 @@ Text *BKE_text_add(Main *bmain, const char *name) ta->curc = 0; ta->sell = ta->lines.first; ta->selc = 0; +} + +Text *BKE_text_add(Main *bmain, const char *name) +{ + Text *ta; + + ta = BKE_libblock_alloc(bmain, ID_TXT, name); + + BKE_text_init(ta); return ta; } diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 88a412d5e95..463ca250ad5 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -580,6 +580,8 @@ void BKE_texture_free(Tex *tex) void BKE_texture_default(Tex *tex) { + /* BLI_assert(MEMCMP_STRUCT_OFS_IS_ZERO(tex, id)); */ /* Not here, can be called with some pointers set. :/ */ + tex->type = TEX_IMAGE; tex->ima = NULL; tex->stype = 0; diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index e4736b1f54c..88c98b6d9d8 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -31,6 +31,7 @@ #include <string.h> +#include <stdlib.h> #include <math.h> #include "MEM_guardedalloc.h" @@ -83,12 +84,10 @@ void BKE_world_free(World *wrld) BKE_world_free_ex(wrld, true); } -World *add_world(Main *bmain, const char *name) +void BKE_world_init(World *wrld) { - World *wrld; + BLI_assert(MEMCMP_STRUCT_OFS_IS_ZERO(wrld, id)); - wrld = BKE_libblock_alloc(bmain, ID_WO, name); - wrld->horr = 0.05f; wrld->horg = 0.05f; wrld->horb = 0.05f; @@ -113,6 +112,15 @@ World *add_world(Main *bmain, const char *name) wrld->preview = NULL; wrld->miststa = 5.0f; wrld->mistdist = 25.0f; +} + +World *add_world(Main *bmain, const char *name) +{ + World *wrld; + + wrld = BKE_libblock_alloc(bmain, ID_WO, name); + + BKE_world_init(wrld); return wrld; } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 2e7969637a3..6545a3b0e67 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -7937,7 +7937,7 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID if (id->flag & LIB_FAKEUSER) id->us= 1; else id->us = 0; id->icon_id = 0; - id->flag &= ~(LIB_ID_RECALC|LIB_ID_RECALC_DATA|LIB_DOIT); + id->flag &= ~(LIB_ID_RECALC | LIB_ID_RECALC_DATA | LIB_DOIT | LIB_MISSING); /* this case cannot be direct_linked: it's just the ID part */ if (bhead->code == ID_ID) { @@ -9615,6 +9615,25 @@ static void give_base_to_groups( } } +static ID *create_placeholder(Main *mainvar, const char *idname, const short flag) +{ + const short idcode = GS(idname); + ListBase *lb = which_libbase(mainvar, idcode); + ID *ph_id = BKE_libblock_alloc_notest(idcode); + + memcpy(ph_id->name, idname, sizeof(ph_id->name)); + BKE_libblock_init_empty(ph_id); + ph_id->lib = mainvar->curlib; + ph_id->flag = flag | LIB_MISSING; + ph_id->us = (flag & LIB_FAKEUSER) ? 1 : 0; + ph_id->icon_id = 0; + + BLI_addtail(lb, ph_id); + id_sort_by_name(lb, ph_id); + + return ph_id; +} + /* returns true if the item was found * but it may already have already been appended/linked */ static ID *link_named_part(Main *mainl, FileData *fd, const short idcode, const char *name) @@ -9758,16 +9777,35 @@ ID *BLO_library_link_named_part_ex( return link_named_part_ex(mainl, fd, idcode, name, flag, scene, v3d); } -static void link_id_part(FileData *fd, Main *mainvar, ID *id, ID **r_id) +static void link_id_part(ReportList *reports, FileData *fd, Main *mainvar, ID *id, ID **r_id) { - BHead *bhead = find_bhead_from_idname(fd, id->name); + BHead *bhead = NULL; + + if (fd) { + bhead = find_bhead_from_idname(fd, id->name); + } + + id->flag &= ~LIB_READ; if (bhead) { - id->flag &= ~LIB_READ; id->flag |= LIB_NEED_EXPAND; // printf("read lib block %s\n", id->name); read_libblock(fd, mainvar, bhead, id->flag, r_id); } + else { + blo_reportf_wrap( + reports, RPT_WARNING, + TIP_("LIB ERROR: %s: '%s' missing from '%s', parent '%s'"), + BKE_idcode_to_name(GS(id->name)), + id->name + 2, + mainvar->curlib->filepath, + library_parent_filepath(mainvar->curlib)); + + /* Generate a placeholder for this ID (simplified version of read_libblock actually...). */ + if (r_id) { + *r_id = create_placeholder(mainvar, id->name, id->flag); + } + } } /* common routine to append/link something from a library */ @@ -10012,6 +10050,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) } else { mainptr->curlib->filedata = NULL; + mainptr->curlib->id.flag |= LIB_MISSING; } if (fd == NULL) { @@ -10021,37 +10060,29 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) } if (fd) { do_it = true; - a = set_listbasepointers(mainptr, lbarray); - while (a--) { - ID *id = lbarray[a]->first; - - while (id) { - ID *idn = id->next; - if (id->flag & LIB_READ) { - ID *realid = NULL; - BLI_remlink(lbarray[a], id); - - link_id_part(fd, mainptr, id, &realid); - if (!realid) { - blo_reportf_wrap( - fd->reports, RPT_WARNING, - TIP_("LIB ERROR: %s: '%s' missing from '%s', parent '%s'"), - BKE_idcode_to_name(GS(id->name)), - id->name + 2, - mainptr->curlib->filepath, - library_parent_filepath(mainptr->curlib)); - } - - change_idid_adr(mainlist, basefd, id, realid); - - MEM_freeN(id); - } - id = idn; + } + a = set_listbasepointers(mainptr, lbarray); + while (a--) { + ID *id = lbarray[a]->first; + + while (id) { + ID *idn = id->next; + if (id->flag & LIB_READ) { + ID *realid = NULL; + BLI_remlink(lbarray[a], id); + + link_id_part(basefd->reports, fd, mainptr, id, &realid); + + BLI_assert(realid != NULL); + + change_idid_adr(mainlist, basefd, id, realid); + + MEM_freeN(id); } + id = idn; } - - BLO_expand_main(fd, mainptr); } + BLO_expand_main(fd, mainptr); } mainptr = mainptr->next; @@ -10059,6 +10090,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) } /* test if there are unread libblocks */ + /* XXX This code block is kept for 2.77, until we are sure it never gets reached anymore. Can be removed later. */ for (mainptr = mainl->next; mainptr; mainptr = mainptr->next) { a = set_listbasepointers(mainptr, lbarray); while (a--) { @@ -10067,10 +10099,12 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) for (id = lbarray[a]->first; id; id = idn) { idn = id->next; if (id->flag & LIB_READ) { + BLI_assert(0); BLI_remlink(lbarray[a], id); blo_reportf_wrap( basefd->reports, RPT_WARNING, - TIP_("LIB ERROR: %s: '%s' unread lib block missing from '%s', parent '%s'"), + TIP_("LIB ERROR: %s: '%s' unread lib block missing from '%s', parent '%s' - " + "Please file a bug report if you see this message"), BKE_idcode_to_name(GS(id->name)), id->name + 2, mainptr->curlib->filepath, diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index ac9e2e36ded..665ae88d833 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -1318,7 +1318,16 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto case ID_GR: tselem_draw_icon_uibut(&arg, ICON_GROUP); break; case ID_LI: - tselem_draw_icon_uibut(&arg, ICON_LIBRARY_DATA_DIRECT); break; + if (tselem->id->flag & LIB_MISSING) { + tselem_draw_icon_uibut(&arg, ICON_LIBRARY_DATA_BROKEN); + } + else if (((Library *)tselem->id)->parent) { + tselem_draw_icon_uibut(&arg, ICON_LIBRARY_DATA_INDIRECT); + } + else { + tselem_draw_icon_uibut(&arg, ICON_LIBRARY_DATA_DIRECT); + } + break; case ID_LS: tselem_draw_icon_uibut(&arg, ICON_LINE_DATA); break; case ID_GD: @@ -1553,10 +1562,15 @@ static void outliner_draw_tree_element( if (tselem->type == 0 && tselem->id->lib) { glPixelTransferf(GL_ALPHA_SCALE, 0.5f); - if (tselem->id->flag & LIB_INDIRECT) + if (tselem->id->flag & LIB_MISSING) { + UI_icon_draw((float)startx + offsx, (float)*starty + 2 * ufac, ICON_LIBRARY_DATA_BROKEN); + } + else if (tselem->id->flag & LIB_INDIRECT) { UI_icon_draw((float)startx + offsx, (float)*starty + 2 * ufac, ICON_LIBRARY_DATA_INDIRECT); - else + } + else { UI_icon_draw((float)startx + offsx, (float)*starty + 2 * ufac, ICON_LIBRARY_DATA_DIRECT); + } glPixelTransferf(GL_ALPHA_SCALE, 1.0f); offsx += UI_UNIT_X; } diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 342245fa393..c2901b8b9a5 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -261,6 +261,8 @@ typedef struct PreviewImage { #define ID_BLEND_PATH(_bmain, _id) ((_id)->lib ? (_id)->lib->filepath : (_bmain)->name) +#define ID_MISSING(_id) (((_id)->flag & LIB_MISSING) != 0) + #ifdef GS # undef GS #endif @@ -280,6 +282,8 @@ enum { LIB_TESTIND = (LIB_NEED_EXPAND | LIB_INDIRECT), LIB_READ = 1 << 4, LIB_NEED_LINK = 1 << 5, + /* tag datablock as a place-holder (because the real one could not be linked from its library e.g.). */ + LIB_MISSING = 1 << 6, LIB_NEW = 1 << 8, LIB_FAKEUSER = 1 << 9, |