Fix #34040: Moving Normal Node with enabled Cycles Material Preview crashes
authorSergey Sharybin <sergey.vfx@gmail.com>
Tue, 5 Feb 2013 12:46:15 +0000 (12:46 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Tue, 5 Feb 2013 12:46:15 +0000 (12:46 +0000)
Issue was caused by couple of circumstances:

- Normal Map node requires tesselated faces to compute tangent space
- All temporary meshes needed for Cycles export were adding to G.main
- Undo pushes would temporary set meshes tessfaces to NULL
- Moving node will cause undo push and tree re-evaluate fr preview

All this leads to threading conflict between preview render and undo
system.

Solved it in  way that all temporary meshes are adding to that exact
Main which was passed to Cycles via BlendData. This required couple
of mechanic changes like adding extra parameter to *_add() functions
and adding some *_ex() functions to make it possible RNA adds objects
to Main passed to new() RNA function.

This was tricky to pass Main to RNA function and IMO that's not so
nice to pass main to function, so ended up with such decision:

- Object.to_mesh() will add temp mesh to G.main
- Added Main.meshes.new_from_object() which does the same as to_mesh,
  but adds temporary mesh to specified Main.

So now all temporary meshes needed for preview render would be added
to preview_main which does not conflict with undo pushes.

Viewport render shall not be an issue because object sync happens from
main thread in this case.

It could be some issues with final render, but that's not so much
likely to happen, so shall be fine.

Thanks to Brecht for review!

70 files changed:
intern/cycles/blender/blender_mesh.cpp
intern/cycles/blender/blender_util.h
source/blender/blenkernel/BKE_action.h
source/blender/blenkernel/BKE_armature.h
source/blender/blenkernel/BKE_brush.h
source/blender/blenkernel/BKE_camera.h
source/blender/blenkernel/BKE_curve.h
source/blender/blenkernel/BKE_group.h
source/blender/blenkernel/BKE_image.h
source/blender/blenkernel/BKE_lamp.h
source/blender/blenkernel/BKE_lattice.h
source/blender/blenkernel/BKE_library.h
source/blender/blenkernel/BKE_mask.h
source/blender/blenkernel/BKE_material.h
source/blender/blenkernel/BKE_mball.h
source/blender/blenkernel/BKE_mesh.h
source/blender/blenkernel/BKE_movieclip.h
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/BKE_object.h
source/blender/blenkernel/BKE_speaker.h
source/blender/blenkernel/BKE_text.h
source/blender/blenkernel/BKE_texture.h
source/blender/blenkernel/BKE_world.h
source/blender/blenkernel/intern/action.c
source/blender/blenkernel/intern/anim_sys.c
source/blender/blenkernel/intern/armature.c
source/blender/blenkernel/intern/brush.c
source/blender/blenkernel/intern/camera.c
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/group.c
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/ipo.c
source/blender/blenkernel/intern/lamp.c
source/blender/blenkernel/intern/lattice.c
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/mask.c
source/blender/blenkernel/intern/material.c
source/blender/blenkernel/intern/mball.c
source/blender/blenkernel/intern/mesh.c
source/blender/blenkernel/intern/movieclip.c
source/blender/blenkernel/intern/node.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/paint.c
source/blender/blenkernel/intern/speaker.c
source/blender/blenkernel/intern/text.c
source/blender/blenkernel/intern/texture.c
source/blender/blenkernel/intern/world.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/animation/keyframing.c
source/blender/editors/armature/poselib.c
source/blender/editors/interface/interface_ops.c
source/blender/editors/mask/mask_ops.c
source/blender/editors/object/object_add.c
source/blender/editors/object/object_group.c
source/blender/editors/physics/rigidbody_constraint.c
source/blender/editors/physics/rigidbody_object.c
source/blender/editors/render/render_shading.c
source/blender/editors/sculpt_paint/paint_ops.c
source/blender/editors/space_action/action_edit.c
source/blender/editors/space_clip/clip_ops.c
source/blender/editors/space_image/image_ops.c
source/blender/editors/space_node/node_add.c
source/blender/editors/space_node/node_edit.c
source/blender/editors/space_node/node_group.c
source/blender/editors/space_node/node_header.c
source/blender/editors/space_text/text_ops.c
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_main_api.c
source/blender/makesrna/intern/rna_object_api.c
source/blender/modifiers/intern/MOD_boolean_util.c

index cdbd2fa8f2fe0608e4b29b73077d40d255f511da..c61a7fafb57f8b00da76b2084b36fab33960b62f 100644 (file)
@@ -435,7 +435,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tri
        mesh_synced.insert(mesh);
 
        /* create derived mesh */
-       BL::Mesh b_mesh = object_to_mesh(b_ob, b_scene, true, !preview);
+       BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview);
        PointerRNA cmesh = RNA_pointer_get(&b_ob_data.ptr, "cycles");
 
        vector<Mesh::Triangle> oldtriangle = mesh->triangles;
@@ -507,7 +507,7 @@ void BlenderSync::sync_mesh_motion(BL::Object b_ob, Mesh *mesh, int motion)
                return;
 
        /* get derived mesh */
-       BL::Mesh b_mesh = object_to_mesh(b_ob, b_scene, true, !preview);
+       BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview);
 
        if(b_mesh) {
                BL::Mesh::vertices_iterator v;
index f134416f2d0bf719e4dac47c19dd4651ac5cc9a9..0947b5a2e9d527e38577b63955f818229ce7dd9c 100644 (file)
@@ -39,9 +39,9 @@ float *BKE_image_get_float_pixels_for_frame(void *image, int frame);
 
 CCL_NAMESPACE_BEGIN
 
-static inline BL::Mesh object_to_mesh(BL::Object self, BL::Scene scene, bool apply_modifiers, bool render)
+static inline BL::Mesh object_to_mesh(BL::BlendData data, BL::Object object, BL::Scene scene, bool apply_modifiers, bool render)
 {
-       return self.to_mesh(scene, apply_modifiers, (render)? 2: 1);
+       return data.meshes.new_from_object(scene, object, apply_modifiers, (render)? 2: 1);
 }
 
 static inline void colorramp_to_array(BL::ColorRamp ramp, float4 *data, int size)
index 4f54f93a7fc891d5552ff3c2a9609a0374cc0604..12c9f6b449f2e2b9bd01a127b3487907e1e91e84 100644 (file)
@@ -44,6 +44,7 @@ struct FCurve;
 struct bPose;
 struct bItasc;
 struct bPoseChannel;
+struct Main;
 struct Object;
 struct Scene;
 struct ID;
@@ -56,7 +57,7 @@ extern "C" {
 /* Action Lib Stuff ----------------- */
 
 /* Allocate a new bAction with the given name */
-struct bAction *add_empty_action(const char name[]);
+struct bAction *add_empty_action(struct Main *bmain, const char name[]);
 
 /* Allocate a copy of the given Action and all its data */     
 struct bAction *BKE_action_copy(struct bAction *src);
index 765a00b8d4b69ce1b4153adee2f0760ea61cc202..fb9e9f4e691b84f1c3f31691a5264e663a24c94d 100644 (file)
@@ -73,7 +73,7 @@ typedef struct PoseTree {
 extern "C" {
 #endif
 
-struct bArmature *BKE_armature_add(const char *name);
+struct bArmature *BKE_armature_add(struct Main *bmain, const char *name);
 struct bArmature *BKE_armature_from_object(struct Object *ob);
 void BKE_armature_bonelist_free(struct ListBase *lb);
 void BKE_armature_free(struct bArmature *arm);
index 91f0525d4f36e69907164094e220eeeccafa555d..cfae15961d73177b1ab32ff176539f586d15a834 100644 (file)
@@ -37,12 +37,13 @@ struct ID;
 struct Brush;
 struct ImBuf;
 struct ImagePool;
+struct Main;
 struct Scene;
 struct wmOperator;
 // enum CurveMappingPreset;
 
 /* datablock functions */
-struct Brush *BKE_brush_add(const char *name);
+struct Brush *BKE_brush_add(struct Main *bmain, const char *name);
 struct Brush *BKE_brush_copy(struct Brush *brush);
 void BKE_brush_make_local(struct Brush *brush);
 void BKE_brush_free(struct Brush *brush);
index 2a27934c038a7cb2bb10de7f4620bdee3706f4a1..057cd79b9e4472b02489692adc85739420d3c2db 100644 (file)
@@ -39,6 +39,7 @@ extern "C" {
 #include "DNA_vec_types.h"
 
 struct Camera;
+struct Main;
 struct Object;
 struct RegionView3D;
 struct RenderData;
@@ -48,7 +49,7 @@ struct View3D;
 
 /* Camera Datablock */
 
-void *BKE_camera_add(const char *name);
+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);
 void BKE_camera_free(struct Camera *ca);
index 536bbecb79b95eb3b664e117313a7a072c47c3cc..358f884f74e3a1536c4194bf4a971f0222064004 100644 (file)
@@ -39,6 +39,7 @@ struct Curve;
 struct EditNurb;
 struct ListBase;
 struct ListBase;
+struct Main;
 struct Nurb;
 struct Object;
 struct Scene;
@@ -57,7 +58,7 @@ struct Scene;
 void BKE_curve_unlink(struct Curve *cu);
 void BKE_curve_free(struct Curve *cu);
 void BKE_curve_editfont_free(struct Curve *cu);
-struct Curve *BKE_curve_add(const char *name, int type);
+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);
 short BKE_curve_type_get(struct Curve *cu);
index 3e9803a908bf9029f34bb239daa2b086b8c31696..8c36a73a088127d6f2e07b143745709532aae23d 100644 (file)
 struct Base;
 struct Group;
 struct GroupObject;
+struct Main;
 struct Object;
 struct bAction;
 struct Scene;
 
 void        BKE_group_free(struct Group *group);
 void        BKE_group_unlink(struct Group *group);
-struct Group *add_group(const char *name);
+struct Group *add_group(struct Main *bmain, const char *name);
 struct Group *BKE_group_copy(struct Group *group);
 int         add_to_group(struct Group *group, struct Object *ob, struct Scene *scene, struct Base *base);
 int         rem_from_group(struct Group *group, struct Object *ob, struct Scene *scene, struct Base *base);
index bfee5e820c3cf4d01f274426b5a38759ffb4539d..f098defb907f82c0676ac251c7310df5209602ce 100644 (file)
@@ -153,12 +153,12 @@ struct ImBuf *BKE_image_pool_acquire_ibuf(struct Image *ima, struct ImageUser *i
 void BKE_image_pool_release_ibuf(struct Image *ima, struct ImBuf *ibuf, struct ImagePool *pool);
 
 /* returns a new image or NULL if it can't load */
-struct Image *BKE_image_load(const char *filepath);
+struct Image *BKE_image_load(struct Main *bmain, const char *filepath);
 /* returns existing Image when filename/type is same (frame optional) */
 struct Image *BKE_image_load_exists(const char *filepath);
 
 /* adds image, adds ibuf, generates color or pattern */
-struct Image *BKE_image_add_generated(unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short uvtestgrid, float color[4]);
+struct Image *BKE_image_add_generated(struct Main *bmain, unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type, float color[4]);
 /* adds image from imbuf, owns imbuf */
 struct Image *BKE_image_add_from_imbuf(struct ImBuf *ibuf);
 
index 244decf9d520d883651d466615c77b1c916c9004..205c7c7d1e61f0bf182d0add7fe061dae6396545 100644 (file)
@@ -37,9 +37,10 @@ extern "C" {
 #endif
 
 struct Lamp;
+struct Main;
 struct Scene;
 
-struct Lamp *BKE_lamp_add(const char *name) WARN_UNUSED;
+struct Lamp *BKE_lamp_add(struct Main *bmain, const char *name) WARN_UNUSED;
 struct Lamp *BKE_lamp_copy(struct Lamp *la) WARN_UNUSED;
 struct Lamp *localize_lamp(struct Lamp *la) WARN_UNUSED;
 void BKE_lamp_make_local(struct Lamp *la);
index fe88f0c580a986716daee521603be82afb3ca8c9..b195af18a8e92f1909bce58241c1270b3cd97f3b 100644 (file)
@@ -35,6 +35,7 @@
  */
 
 struct Lattice;
+struct Main;
 struct Object;
 struct Scene;
 struct DerivedMesh;
@@ -42,7 +43,7 @@ struct BPoint;
 struct MDeformVert;
 
 void BKE_lattice_resize(struct Lattice *lt, int u, int v, int w, struct Object *ltOb);
-struct Lattice *BKE_lattice_add(const char *name);
+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);
 void BKE_lattice_make_local(struct Lattice *lt);
index b9bb67fa509b8d130166e60462aeea0c01b79bbb..5aa82be0541f999aa3a4ff4281173604dfa1e544 100644 (file)
@@ -51,6 +51,12 @@ __attribute__((warn_unused_result))
 __attribute__((nonnull))
 #endif
 ;
+void *BKE_libblock_copy_ex(struct Main *bmain, struct ID *id)
+#ifdef __GNUC__
+__attribute__((warn_unused_result))
+__attribute__((nonnull))
+#endif
+;
 void *BKE_libblock_copy(struct ID *id)
 #ifdef __GNUC__
 __attribute__((warn_unused_result))
index cc15ceecbac0ca35881226ff42a4f79a399ebbe9..b40ad4814f0b6881a644cd65d6d6885cfba9a55c 100644 (file)
@@ -98,7 +98,7 @@ void BKE_mask_point_select_set(struct MaskSplinePoint *point, const short do_sel
 void BKE_mask_point_select_set_handle(struct MaskSplinePoint *point, const short do_select);
 
 /* general */
-struct Mask *BKE_mask_new(const char *name);
+struct Mask *BKE_mask_new(struct Main *bmain, const char *name);
 struct Mask *BKE_mask_copy_nolib(struct Mask *mask);
 struct Mask *BKE_mask_copy(struct Mask *mask);
 
index dd1b1a7752bffeb8e90180e0580d37fee5655460..350eaf23f6f9812d516bb393c4019c6633117462 100644 (file)
@@ -52,7 +52,7 @@ void BKE_material_free_ex(struct Material *ma, int do_id_user);
 void test_object_materials(struct ID *id);
 void resize_object_material(struct Object *ob, const short totcol);
 void init_material(struct Material *ma);
-struct Material *BKE_material_add(const char *name);
+struct Material *BKE_material_add(struct Main *bmain, const char *name);
 struct Material *BKE_material_copy(struct Material *ma);
 struct Material *localize_material(struct Material *ma);
 struct Material *give_node_material(struct Material *ma); /* returns node material or self */
index 7a0eea1b009b4f85d47ac0a2c118809344b03ef4..662bfab10a11365b1f14a4df49c71c2ce0a964ca 100644 (file)
@@ -32,6 +32,7 @@
  *  \since March 2001
  *  \author nzc
  */
+struct Main;
 struct MetaBall;
 struct Object;
 struct Scene;
@@ -39,7 +40,7 @@ struct MetaElem;
 
 void BKE_mball_unlink(struct MetaBall *mb);
 void BKE_mball_free(struct MetaBall *mb);
-struct MetaBall *BKE_mball_add(const char *name);
+struct MetaBall *BKE_mball_add(struct Main *bmain, const char *name);
 struct MetaBall *BKE_mball_copy(struct MetaBall *mb);
 
 void BKE_mball_make_local(struct MetaBall *mb);
index cfe562e231c1ec0dd01e553626fac763c6eb9751..24535eb1fd6cc18e6f4451b84175d9d7c7f7e423 100644 (file)
@@ -39,6 +39,7 @@ struct DispList;
 struct ListBase;
 struct BMEditMesh;
 struct BMesh;
+struct Main;
 struct Mesh;
 struct MPoly;
 struct MLoop;
@@ -146,7 +147,8 @@ void BKE_mesh_flush_select_from_verts(struct Mesh *me);
 
 void BKE_mesh_unlink(struct Mesh *me);
 void BKE_mesh_free(struct Mesh *me, int unlink);
-struct Mesh *BKE_mesh_add(const char *name);
+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);
 void mesh_update_customdata_pointers(struct Mesh *me, const short do_ensure_tess_cd);
 
index 25d2678ea47766aec7a0d080d207bede154bc494..5777a4094bccb86f1beb6bcc893673f4d0f5435f 100644 (file)
@@ -43,7 +43,7 @@ struct MovieDistortion;
 void BKE_movieclip_free(struct MovieClip *clip);
 void BKE_movieclip_unlink(struct Main *bmain, struct MovieClip *clip);
 
-struct MovieClip *BKE_movieclip_file_add(const char *name);
+struct MovieClip *BKE_movieclip_file_add(struct Main *bmain, const char *name);
 void BKE_movieclip_reload(struct MovieClip *clip);
 
 struct ImBuf *BKE_movieclip_get_ibuf(struct MovieClip *clip, struct MovieClipUser *user);
index 718fa2f9ecd7d78b6eea109a7382ab351d00bf19..5024b3636c5b2453a6dbc02299fdd36faf65b402 100644 (file)
@@ -299,7 +299,7 @@ struct bNodeTreeType *ntreeGetType(int type);
 struct bNodeType *ntreeGetNodeType(struct bNodeTree *ntree);
 struct bNodeSocketType *ntreeGetSocketType(int type);
 
-struct bNodeTree *ntreeAddTree(const char *name, int type, int nodetype);
+struct bNodeTree *ntreeAddTree(struct Main *bmain, const char *name, int type, int nodetype);
 void              ntreeInitTypes(struct bNodeTree *ntree);
 
 /* copy/free funcs, need to manage ID users */
index bfae1bd239033b08c7915d0c446564c77dc429e9..54189e26c92e0163c5751d4f369184c34b459ac3 100644 (file)
@@ -49,6 +49,7 @@ struct bAction;
 struct RenderData;
 struct rctf;
 struct MovieClip;
+struct Main;
 
 void BKE_object_workob_clear(struct Object *workob);
 void BKE_object_workob_calc_parent(struct Scene *scene, struct Object *ob, struct Object *workob);
@@ -78,12 +79,12 @@ void BKE_object_unlink(struct Object *ob);
 int  BKE_object_exists_check(struct Object *obtest);
 int BKE_object_is_in_editmode(struct Object *ob);
 
-struct Object *BKE_object_add_only_object(int type, const char *name);
+struct Object *BKE_object_add_only_object(struct Main *bmain, int type, const char *name);
 struct Object *BKE_object_add(struct Scene *scene, int type);
 void *BKE_object_obdata_add_from_type(int type);
 
+struct Object *BKE_object_copy_ex(struct Main *bmain, struct Object *ob, int copy_caches);
 struct Object *BKE_object_copy(struct Object *ob);
-struct Object *BKE_object_copy_with_caches(struct Object *ob);
 void BKE_object_make_local(struct Object *ob);
 int  BKE_object_is_libdata(struct Object *ob);
 int  BKE_object_obdata_is_libdata(struct Object *ob);
index 52c177fce57c3e0b560ac3fb5def203688e9dbaf..e2f0fa50a86fd96e35a821b6792feaf1fd2b9246 100644 (file)
@@ -33,7 +33,9 @@
  *  \brief General operations for speakers.
  */
 
-void *BKE_speaker_add(const char *name);
+struct Main;
+
+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);
 void BKE_speaker_free(struct Speaker *spk);
index be30eba0559273f85d566238758c96e80f8a8120..dc84bc67647f38b7627a7caf915d5cfd3c395f9f 100644 (file)
@@ -45,10 +45,10 @@ struct SpaceText;
 void                   BKE_text_free           (struct Text *text);
 void                   txt_set_undostate       (int u);
 int                    txt_get_undostate       (void);
-struct Text*   BKE_text_add    (const char *name);
+struct Text*   BKE_text_add    (struct Main *bmain, const char *name);
 int                            txt_extended_ascii_as_utf8(char **str);
 int                            BKE_text_reload         (struct Text *text);
-struct Text*   BKE_text_load           (const char *file, const char *relpath);
+struct Text*   BKE_text_load   (struct Main *bmain, const char *file, const char *relpath);
 struct Text*   BKE_text_copy           (struct Text *ta);
 void                   BKE_text_unlink         (struct Main *bmain, struct Text *text);
 void                   BKE_text_clear      (struct Text *text);
index 78fdd26c9e04017bf4541a6e3622c9ca081ec898..f1796373367c6a719f0edefa19df121b7825a7e2 100644 (file)
@@ -44,6 +44,7 @@ struct EnvMap;
 struct HaloRen;
 struct Lamp;
 struct LampRen;
+struct Main;
 struct Material;
 struct MTex;
 struct OceanTex;
@@ -69,7 +70,7 @@ int colorband_element_remove(struct ColorBand *coba, int index);
 void colorband_update_sort(struct ColorBand *coba);
 
 void default_tex(struct Tex *tex);
-struct Tex *add_texture(const char *name);
+struct Tex *add_texture(struct Main *bmain, const char *name);
 void tex_set_type(struct Tex *tex, int type);
 void default_mtex(struct MTex *mtex);
 struct MTex *add_mtex(void);
index 7a23bff0184048d570ddf8f7fe96e9ccaf5d74aa..6bb35e46539371bd3cada049def7e3fbfa6e85fc 100644 (file)
  *  \author nzc
  */
 
+struct Main;
 struct World;
 
 void BKE_world_free(struct World *sc);
 void BKE_world_free_ex(struct World *sc, int do_id_user);
-struct World *add_world(const char *name);
+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);
 void BKE_world_make_local(struct World *wrld);
index 5ccf91464405a22565e21931e3c6fdacda081d06..509442b1d4ee39eaf8cc74f94f5172f5f1ee9cb6 100644 (file)
 
 /* ***************** Library data level operations on action ************** */
 
-bAction *add_empty_action(const char name[])
+bAction *add_empty_action(Main *bmain, const char name[])
 {
        bAction *act;
        
-       act = BKE_libblock_alloc(&G.main->action, ID_AC, name);
+       act = BKE_libblock_alloc(&bmain->action, ID_AC, name);
        
        return act;
 }      
index df2cc7cc461a056d06e418674ce9515d422daadf..74e44eab2817aa1379949ed7d1368e0d304dab8a 100644 (file)
@@ -499,7 +499,7 @@ void BKE_animdata_separate_by_basepath(ID *srcID, ID *dstID, ListBase *basepaths
        if (srcAdt->action) {
                /* set up an action if necessary, and name it in a similar way so that it can be easily found again */
                if (dstAdt->action == NULL) {
-                       dstAdt->action = add_empty_action(srcAdt->action->id.name + 2);
+                       dstAdt->action = add_empty_action(G.main, srcAdt->action->id.name + 2);
                }
                else if (dstAdt->action == srcAdt->action) {
                        printf("Argh! Source and Destination share animation! ('%s' and '%s' both use '%s') Making new empty action\n",
@@ -507,7 +507,7 @@ void BKE_animdata_separate_by_basepath(ID *srcID, ID *dstID, ListBase *basepaths
                        
                        /* TODO: review this... */
                        id_us_min(&dstAdt->action->id);
-                       dstAdt->action = add_empty_action(dstAdt->action->id.name + 2);
+                       dstAdt->action = add_empty_action(G.main, dstAdt->action->id.name + 2);
                }
                        
                /* loop over base paths, trying to fix for each one... */
index 3a705a07e2277bb66a49fe3f93c9be38828052a1..b678ef6d93ce9206e2d759fa63b38aba453c2e71 100644 (file)
 
 /* **************** Generic Functions, data level *************** */
 
-bArmature *BKE_armature_add(const char *name)
+bArmature *BKE_armature_add(Main *bmain, const char *name)
 {
        bArmature *arm;
 
-       arm = BKE_libblock_alloc(&G.main->armature, ID_AR, name);
+       arm = BKE_libblock_alloc(&bmain->armature, ID_AR, name);
        arm->deformflag = ARM_DEF_VGROUP | ARM_DEF_ENVELOPE;
        arm->flag = ARM_COL_CUSTOM; /* custom bone-group colors */
        arm->layer = 1;
index 70eaa00b82ec2d6f2e0d93f264f24dc68021ea7a..9a32a50ca0022d7c38944bb1c671e189d8d872a6 100644 (file)
@@ -109,11 +109,11 @@ static void brush_defaults(Brush *brush)
 
 /* Datablock add/copy/free/make_local */
 
-Brush *BKE_brush_add(const char *name)
+Brush *BKE_brush_add(Main *bmain, const char *name)
 {
        Brush *brush;
 
-       brush = BKE_libblock_alloc(&G.main->brush, ID_BR, name);
+       brush = BKE_libblock_alloc(&bmain->brush, ID_BR, name);
 
        /* enable fake user by default */
        brush->id.flag |= LIB_FAKEUSER;
@@ -419,7 +419,7 @@ int BKE_brush_texture_set_nr(Brush *brush, int nr)
        idtest = (ID *)BLI_findlink(&G.main->tex, nr - 1);
        if (idtest == NULL) { /* new tex */
                if (id) idtest = (ID *)BKE_texture_copy((Tex *)id);
-               else idtest = (ID *)add_texture("Tex");
+               else idtest = (ID *)add_texture(G.main, "Tex");
                idtest->us--;
        }
        if (idtest != id) {
index d1842b998317af4337b3963c0999103a0982db35..34c2d144f4cc034a3bbe1cbd928339c42eeb1d44 100644 (file)
 
 /****************************** Camera Datablock *****************************/
 
-void *BKE_camera_add(const char *name)
+void *BKE_camera_add(Main *bmain, const char *name)
 {
        Camera *cam;
        
-       cam =  BKE_libblock_alloc(&G.main->camera, ID_CA, name);
+       cam =  BKE_libblock_alloc(&bmain->camera, ID_CA, name);
 
        cam->lens = 35.0f;
        cam->sensor_x = DEFAULT_SENSOR_WIDTH;
index a6e68b9b2d52a137ab78757e7f5461bbe8e567f7..5f7662f50041eedb8f2f6f1fc7030d75bbbe6b60 100644 (file)
@@ -167,11 +167,11 @@ void BKE_curve_free(Curve *cu)
                MEM_freeN(cu->tb);
 }
 
-Curve *BKE_curve_add(const char *name, int type)
+Curve *BKE_curve_add(Main *bmain, const char *name, int type)
 {
        Curve *cu;
 
-       cu = BKE_libblock_alloc(&G.main->curve, ID_CU, name);
+       cu = BKE_libblock_alloc(&bmain->curve, 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;
index 20d874e7243b1577fb9eea2d93006de089f46006..639d256a06727f41ac09ac603403c31de066e01f 100644 (file)
@@ -127,11 +127,11 @@ void BKE_group_unlink(Group *group)
        group->id.us = 0;
 }
 
-Group *add_group(const char *name)
+Group *add_group(Main *bmain, const char *name)
 {
        Group *group;
        
-       group = BKE_libblock_alloc(&G.main->group, ID_GR, name);
+       group = BKE_libblock_alloc(&bmain->group, ID_GR, name);
        group->layer = (1 << 20) - 1;
        return group;
 }
index 82b0d2318696f285efbd0c4cee6e8f16e218ee8e..39d76eb36f1b193114e21345980cbff52075c5b3 100644 (file)
@@ -242,11 +242,11 @@ void BKE_image_free(Image *ima)
 }
 
 /* only image block itself */
-static Image *image_alloc(const char *name, short source, short type)
+static Image *image_alloc(Main *bmain, const char *name, short source, short type)
 {
        Image *ima;
 
-       ima = BKE_libblock_alloc(&G.main->image, ID_IM, name);
+       ima = BKE_libblock_alloc(&bmain->image, ID_IM, name);
        if (ima) {
                ima->ok = IMA_OK;
 
@@ -325,7 +325,7 @@ static void image_assign_ibuf(Image *ima, ImBuf *ibuf, int index, int frame)
 /* empty image block, of similar type and filename */
 Image *BKE_image_copy(Image *ima)
 {
-       Image *nima = image_alloc(ima->id.name + 2, ima->source, ima->type);
+       Image *nima = image_alloc(G.main, ima->id.name + 2, ima->source, ima->type);
 
        BLI_strncpy(nima->name, ima->name, sizeof(ima->name));
 
@@ -568,7 +568,7 @@ static void image_init_color_management(Image *ima)
        }
 }
 
-Image *BKE_image_load(const char *filepath)
+Image *BKE_image_load(Main *bmain, const char *filepath)
 {
        Image *ima;
        int file, len;
@@ -576,7 +576,7 @@ Image *BKE_image_load(const char *filepath)
        char str[FILE_MAX];
 
        BLI_strncpy(str, filepath, sizeof(str));
-       BLI_path_abs(str, G.main->name);
+       BLI_path_abs(str, bmain->name);
 
        /* exists? */
        file = BLI_open(str, O_BINARY | O_RDONLY, 0);
@@ -589,7 +589,7 @@ Image *BKE_image_load(const char *filepath)
        while (len > 0 && filepath[len - 1] != '/' && filepath[len - 1] != '\\') len--;
        libname = filepath + len;
 
-       ima = image_alloc(libname, IMA_SRC_FILE, IMA_TYPE_IMAGE);
+       ima = image_alloc(bmain, libname, IMA_SRC_FILE, IMA_TYPE_IMAGE);
        BLI_strncpy(ima->name, filepath, sizeof(ima->name));
 
        if (BLI_testextensie_array(filepath, imb_ext_movie))
@@ -631,7 +631,7 @@ Image *BKE_image_load_exists(const char *filepath)
                }
        }
 
-       return BKE_image_load(filepath);
+       return BKE_image_load(G.main, filepath);
 }
 
 static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type,
@@ -691,10 +691,10 @@ static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char
 }
 
 /* adds new image block, creates ImBuf and initializes color */
-Image *BKE_image_add_generated(unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type, float color[4])
+Image *BKE_image_add_generated(Main *bmain, unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type, float color[4])
 {
        /* on save, type is changed to FILE in editsima.c */
-       Image *ima = image_alloc(name, IMA_SRC_GENERATED, IMA_TYPE_UV_TEST);
+       Image *ima = image_alloc(bmain, name, IMA_SRC_GENERATED, IMA_TYPE_UV_TEST);
 
        if (ima) {
                ImBuf *ibuf;
@@ -720,7 +720,7 @@ Image *BKE_image_add_from_imbuf(ImBuf *ibuf)
        /* on save, type is changed to FILE in editsima.c */
        Image *ima;
 
-       ima = image_alloc(BLI_path_basename(ibuf->name), IMA_SRC_FILE, IMA_TYPE_IMAGE);
+       ima = image_alloc(G.main, BLI_path_basename(ibuf->name), IMA_SRC_FILE, IMA_TYPE_IMAGE);
 
        if (ima) {
                BLI_strncpy(ima->name, ibuf->name, FILE_MAX);
@@ -2104,7 +2104,7 @@ Image *BKE_image_verify_viewer(int type, const char *name)
                                break;
 
        if (ima == NULL)
-               ima = image_alloc(name, IMA_SRC_VIEWER, type);
+               ima = image_alloc(G.main, name, IMA_SRC_VIEWER, type);
 
        /* happens on reload, imagewindow cannot be image user when hidden*/
        if (ima->id.us == 0)
index 59dd02849ddf59618a29edb209f003cece1df862..c5364744b2dba1568415842b8530fa010c6e846c 100644 (file)
@@ -1548,7 +1548,7 @@ static void ipo_to_animdata(ID *id, Ipo *ipo, char actname[], char constname[],
                        
                        BLI_snprintf(nameBuf, sizeof(nameBuf), "CDA:%s", ipo->id.name + 2);
                        
-                       adt->action = add_empty_action(nameBuf);
+                       adt->action = add_empty_action(G.main, nameBuf);
                        if (G.debug & G_DEBUG) printf("\t\tadded new action - '%s'\n", nameBuf);
                }
                
@@ -2093,7 +2093,7 @@ void do_versions_ipos_to_animato(Main *main)
                        bAction *new_act;
                        
                        /* add a new action for this, and convert all data into that action */
-                       new_act = add_empty_action(id->name + 2);
+                       new_act = add_empty_action(main, id->name + 2);
                        ipo_to_animato(NULL, ipo, NULL, NULL, NULL, NULL, &new_act->curves, &drivers);
                        new_act->idroot = ipo->blocktype;
                }
index 2f37db846f3e88a7d0293760899111e50a25eaa9..32cc5c6c22ee3ac44d48eadc41cdeca8ee6f1980 100644 (file)
 #include "BKE_main.h"
 #include "BKE_node.h"
 
-Lamp *BKE_lamp_add(const char *name)
+Lamp *BKE_lamp_add(Main *bmain, const char *name)
 {
        Lamp *la;
        
-       la =  BKE_libblock_alloc(&G.main->lamp, ID_LA, name);
+       la =  BKE_libblock_alloc(&bmain->lamp, ID_LA, name);
        
        la->r = la->g = la->b = la->k = 1.0f;
        la->haint = la->energy = 1.0f;
index 05d7933e1b5bbc97a6ff4773d0011aef9f59f221..fd57a88e279c4f64164937261c23a6eb20d16d6f 100644 (file)
@@ -180,11 +180,11 @@ void BKE_lattice_resize(Lattice *lt, int uNew, int vNew, int wNew, Object *ltOb)
        MEM_freeN(vertexCos);
 }
 
-Lattice *BKE_lattice_add(const char *name)
+Lattice *BKE_lattice_add(Main *bmain, const char *name)
 {
        Lattice *lt;
        
-       lt = BKE_libblock_alloc(&G.main->latt, ID_LT, name);
+       lt = BKE_libblock_alloc(&bmain->latt, ID_LT, name);
        
        lt->flag = LT_GRID;
        
index 817068ae41eb274e00195d86c949a0540822e572..cd40f752b03c1588e95c0a1732d75dee9b11c352 100644 (file)
@@ -742,13 +742,13 @@ void BKE_libblock_copy_data(ID *id, const ID *id_from, const short do_action)
 }
 
 /* used everywhere in blenkernel */
-void *BKE_libblock_copy(ID *id)
+void *BKE_libblock_copy_ex(Main *bmain, ID *id)
 {
        ID *idn;
        ListBase *lb;
        size_t idn_len;
 
-       lb = which_libbase(G.main, GS(id->name));
+       lb = which_libbase(bmain, GS(id->name));
        idn = BKE_libblock_alloc(lb, GS(id->name), id->name + 2);
 
        assert(idn != NULL);
@@ -769,6 +769,11 @@ void *BKE_libblock_copy(ID *id)
        return idn;
 }
 
+void *BKE_libblock_copy(ID *id)
+{
+       return BKE_libblock_copy_ex(G.main, id);
+}
+
 static void BKE_library_free(Library *lib)
 {
        if (lib->packedfile)
index bda924060d5a785b342be47eff1fed2f92b41191..960432d6b3d7c75f7ccc57b010f5195a1a607aee 100644 (file)
@@ -698,18 +698,18 @@ void BKE_mask_point_select_set_handle(MaskSplinePoint *point, const short do_sel
 }
 
 /* only mask block itself */
-static Mask *mask_alloc(const char *name)
+static Mask *mask_alloc(Main *bmain, const char *name)
 {
        Mask *mask;
 
-       mask = BKE_libblock_alloc(&G.main->mask, ID_MSK, name);
+       mask = BKE_libblock_alloc(&bmain->mask, ID_MSK, name);
 
        mask->id.flag |= LIB_FAKEUSER;
 
        return mask;
 }
 
-Mask *BKE_mask_new(const char *name)
+Mask *BKE_mask_new(Main *bmain, const char *name)
 {
        Mask *mask;
        char mask_name[MAX_ID_NAME - 2];
@@ -719,7 +719,7 @@ Mask *BKE_mask_new(const char *name)
        else
                strcpy(mask_name, "Mask");
 
-       mask = mask_alloc(mask_name);
+       mask = mask_alloc(bmain, mask_name);
 
        /* arbitrary defaults */
        mask->sfra = 1;
index f19dc93198d1cdb01917c0f90b58e5bd5d88f6e9..47117658b5e206a1d8a8d2b9cb62405250e4c1df 100644 (file)
@@ -206,11 +206,11 @@ void init_material(Material *ma)
        ma->preview = NULL;
 }
 
-Material *BKE_material_add(const char *name)
+Material *BKE_material_add(Main *bmain, const char *name)
 {
        Material *ma;
 
-       ma = BKE_libblock_alloc(&G.main->mat, ID_MA, name);
+       ma = BKE_libblock_alloc(&bmain->mat, ID_MA, name);
        
        init_material(ma);
        
@@ -1778,7 +1778,7 @@ static short convert_tfacenomaterial(Main *main, Mesh *me, MTFace *tf, int flag)
        }
        /* create a new material */
        else {
-               ma = BKE_material_add(idname + 2);
+               ma = BKE_material_add(main, idname + 2);
 
                if (ma) {
                        printf("TexFace Convert: Material \"%s\" created.\n", idname + 2);
index b3f71e58e9f53a9fc0ee58304a8f7b6d24310639..d939b9cc3c01c42de3334aba70a0c12bc7358d22 100644 (file)
@@ -196,11 +196,11 @@ void BKE_mball_free(MetaBall *mb)
        if (mb->disp.first) BKE_displist_free(&mb->disp);
 }
 
-MetaBall *BKE_mball_add(const char *name)
+MetaBall *BKE_mball_add(Main *bmain, const char *name)
 {
        MetaBall *mb;
        
-       mb = BKE_libblock_alloc(&G.main->mball, ID_MB, name);
+       mb = BKE_libblock_alloc(&bmain->mball, ID_MB, name);
        
        mb->size[0] = mb->size[1] = mb->size[2] = 1.0;
        mb->texflag = MB_AUTOSPACE;
index dba2fd5070690d7eb6de2f9f9ab1a9705b00f8be..20ccc33bc4ea9fcc48ae3a8095a6a1a8fbdc5d91 100644 (file)
@@ -445,11 +445,11 @@ static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata)
        mesh->totface = 0;
 }
 
-Mesh *BKE_mesh_add(const char *name)
+Mesh *BKE_mesh_add(Main *bmain, const char *name)
 {
        Mesh *me;
        
-       me = BKE_libblock_alloc(&G.main->mesh, ID_ME, name);
+       me = BKE_libblock_alloc(&bmain->mesh, ID_ME, name);
        
        me->size[0] = me->size[1] = me->size[2] = 1.0;
        me->smoothresh = 30;
@@ -466,7 +466,7 @@ Mesh *BKE_mesh_add(const char *name)
        return me;
 }
 
-Mesh *BKE_mesh_copy(Mesh *me)
+Mesh *BKE_mesh_copy_ex(Main *bmain, Mesh *me)
 {
        Mesh *men;
        MTFace *tface;
@@ -474,7 +474,7 @@ Mesh *BKE_mesh_copy(Mesh *me)
        int a, i;
        const int do_tessface = ((me->totface != 0) && (me->totpoly == 0)); /* only do tessface if we have no polys */
        
-       men = BKE_libblock_copy(&me->id);
+       men = BKE_libblock_copy_ex(bmain, &me->id);
        
        men->mat = MEM_dupallocN(me->mat);
        for (a = 0; a < men->totcol; a++) {
@@ -527,6 +527,11 @@ Mesh *BKE_mesh_copy(Mesh *me)
        return men;
 }
 
+Mesh *BKE_mesh_copy(Mesh *me)
+{
+       return BKE_mesh_copy_ex(G.main, me);
+}
+
 BMesh *BKE_mesh_to_bmesh(Mesh *me, Object *ob)
 {
        BMesh *bm;
@@ -1497,7 +1502,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int use_orco_u
                }
 
                /* make mesh */
-               me = BKE_mesh_add("Mesh");
+               me = BKE_mesh_add(G.main, "Mesh");
                me->totvert = totvert;
                me->totedge = totedge;
                me->totloop = totloop;
@@ -1519,7 +1524,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int use_orco_u
                BKE_mesh_calc_edges(me, TRUE);
        }
        else {
-               me = BKE_mesh_add("Mesh");
+               me = BKE_mesh_add(G.main, "Mesh");
                DM_to_mesh(dm, me, ob);
        }
 
@@ -1635,7 +1640,7 @@ void BKE_mesh_from_curve(Scene *scene, Object *ob)
        BLI_edgehash_free(eh, NULL);
 
        if (edges.first) {
-               Curve *cu = BKE_curve_add(ob->id.name + 2, OB_CURVE);
+               Curve *cu = BKE_curve_add(G.main, ob->id.name + 2, OB_CURVE);
                cu->flag |= CU_3D;
 
                while (edges.first) {
index 69e368f0d08c095aa3b5d43c2988a5a6917eca4d..943d9e9452a0511e9e2f80bfed967f0fdb70dd5e 100644 (file)
@@ -479,11 +479,11 @@ static void put_imbuf_cache(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf, i
 /*********************** common functions *************************/
 
 /* only image block itself */
-static MovieClip *movieclip_alloc(const char *name)
+static MovieClip *movieclip_alloc(Main *bmain, const char *name)
 {
        MovieClip *clip;
 
-       clip = BKE_libblock_alloc(&G.main->movieclip, ID_MC, name);
+       clip = BKE_libblock_alloc(&bmain->movieclip, ID_MC, name);
 
        clip->aspx = clip->aspy = 1.0f;
 
@@ -542,7 +542,7 @@ static void detect_clip_source(MovieClip *clip)
  * otherwise creates new.
  * does not load ibuf itself
  * pass on optional frame for #name images */
-MovieClip *BKE_movieclip_file_add(const char *name)
+MovieClip *BKE_movieclip_file_add(Main *bmain, const char *name)
 {
        MovieClip *clip;
        int file, len;
@@ -550,7 +550,7 @@ MovieClip *BKE_movieclip_file_add(const char *name)
        char str[FILE_MAX], strtest[FILE_MAX];
 
        BLI_strncpy(str, name, sizeof(str));
-       BLI_path_abs(str, G.main->name);
+       BLI_path_abs(str, bmain->name);
 
        /* exists? */
        file = BLI_open(str, O_BINARY | O_RDONLY, 0);
@@ -559,7 +559,7 @@ MovieClip *BKE_movieclip_file_add(const char *name)
        close(file);
 
        /* ** first search an identical clip ** */
-       for (clip = G.main->movieclip.first; clip; clip = clip->id.next) {
+       for (clip = bmain->movieclip.first; clip; clip = clip->id.next) {
                BLI_strncpy(strtest, clip->name, sizeof(clip->name));
                BLI_path_abs(strtest, G.main->name);
 
@@ -580,7 +580,7 @@ MovieClip *BKE_movieclip_file_add(const char *name)
                len--;
        libname = name + len;
 
-       clip = movieclip_alloc(libname);
+       clip = movieclip_alloc(bmain, libname);
        BLI_strncpy(clip->name, name, sizeof(clip->name));
 
        detect_clip_source(clip);
index 2062cc01d02794e4702d7e710fa1c2666dc35e37..97bee320ecb654eb266ccdef5e6b34fb12de69d0 100644 (file)
@@ -656,7 +656,7 @@ void nodeDetachNode(struct bNode *node)
        }
 }
 
-bNodeTree *ntreeAddTree(const char *name, int type, int nodetype)
+bNodeTree *ntreeAddTree(Main *bmain, const char *name, int type, int nodetype)
 {
        bNodeTree *ntree;
        bNodeType *ntype;
@@ -670,7 +670,7 @@ bNodeTree *ntreeAddTree(const char *name, int type, int nodetype)
                BLI_strncpy(ntree->id.name + 2, name, sizeof(ntree->id.name));
        }
        else
-               ntree = BKE_libblock_alloc(&G.main->nodetree, ID_NT, name);
+               ntree = BKE_libblock_alloc(&bmain->nodetree, ID_NT, name);
        
        ntree->type = type;
        ntree->nodetype = nodetype;
index aac1d9f1f7ba83bc0d5f3dcc4bef6d78223b8393..2312d801e0dd1c2d9c8a1f31ba2e4f6549370e90 100644 (file)
@@ -829,16 +829,16 @@ int BKE_object_exists_check(Object *obtest)
 void *BKE_object_obdata_add_from_type(int type)
 {
        switch (type) {
-               case OB_MESH:      return BKE_mesh_add("Mesh");
-               case OB_CURVE:     return BKE_curve_add("Curve", OB_CURVE);
-               case OB_SURF:      return BKE_curve_add("Surf", OB_SURF);
-               case OB_FONT:      return BKE_curve_add("Text", OB_FONT);
-               case OB_MBALL:     return BKE_mball_add("Meta");
-               case OB_CAMERA:    return BKE_camera_add("Camera");
-               case OB_LAMP:      return BKE_lamp_add("Lamp");
-               case OB_LATTICE:   return BKE_lattice_add("Lattice");
-               case OB_ARMATURE:  return BKE_armature_add("Armature");
-               case OB_SPEAKER:   return BKE_speaker_add("Speaker");
+               case OB_MESH:      return BKE_mesh_add(G.main, "Mesh");
+               case OB_CURVE:     return BKE_curve_add(G.main, "Curve", OB_CURVE);
+               case OB_SURF:      return BKE_curve_add(G.main, "Surf", OB_SURF);
+               case OB_FONT:      return BKE_curve_add(G.main, "Text", OB_FONT);
+               case OB_MBALL:     return BKE_mball_add(G.main, "Meta");
+               case OB_CAMERA:    return BKE_camera_add(G.main, "Camera");
+               case OB_LAMP:      return BKE_lamp_add(G.main, "Lamp");
+               case OB_LATTICE:   return BKE_lattice_add(G.main, "Lattice");
+               case OB_ARMATURE:  return BKE_armature_add(G.main, "Armature");
+               case OB_SPEAKER:   return BKE_speaker_add(G.main, "Speaker");
                case OB_EMPTY:     return NULL;
                default:
                        printf("BKE_object_obdata_add_from_type: Internal error, bad type: %d\n", type);
@@ -867,14 +867,14 @@ static const char *get_obdata_defname(int type)
 }
 
 /* more general add: creates minimum required data, but without vertices etc. */
-Object *BKE_object_add_only_object(int type, const char *name)
+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(&G.main->object, ID_OB, name);
+       ob = BKE_libblock_alloc(&bmain->object, ID_OB, name);
 
        /* default object vars */
        ob->type = type;
@@ -960,7 +960,7 @@ Object *BKE_object_add(struct Scene *scene, int type)
        char name[MAX_ID_NAME];
 
        BLI_strncpy(name, get_obdata_defname(type), sizeof(name));
-       ob = BKE_object_add_only_object(type, name);
+       ob = BKE_object_add_only_object(G.main, type, name);
 
        ob->data = BKE_object_obdata_add_from_type(type);
 
@@ -1226,13 +1226,13 @@ void BKE_object_transform_copy(Object *ob_tar, const Object *ob_src)
        copy_v3_v3(ob_tar->size, ob_src->size);
 }
 
-static Object *object_copy_do(Object *ob, int copy_caches)
+Object *BKE_object_copy_ex(Main *bmain, Object *ob, int copy_caches)
 {
        Object *obn;
        ModifierData *md;
        int a;
 
-       obn = BKE_libblock_copy(&ob->id);
+       obn = BKE_libblock_copy_ex(bmain, &ob->id);
        
        if (ob->totcol) {
                obn->mat = MEM_dupallocN(ob->mat);
@@ -1308,13 +1308,7 @@ static Object *object_copy_do(Object *ob, int copy_caches)
 /* copy objects, will re-initialize cached simulation data */
 Object *BKE_object_copy(Object *ob)
 {
-       return object_copy_do(ob, FALSE);
-}
-
-/* copy objects, will duplicate cached simulation data */
-Object *BKE_object_copy_with_caches(Object *ob)
-{
-       return object_copy_do(ob, TRUE);
+       return BKE_object_copy_ex(G.main, ob, FALSE);
 }
 
 static void extern_local_object(Object *ob)
index dc8aed91c00a9cf14985779485074faca8bec3af..d34d5eaa2508f232d153454511ffe70af4eecedb 100644 (file)
@@ -43,6 +43,7 @@
 
 #include "BKE_brush.h"
 #include "BKE_context.h"
+#include "BKE_global.h"
 #include "BKE_library.h"
 #include "BKE_paint.h"
 #include "BKE_subsurf.h"
@@ -179,7 +180,7 @@ void BKE_paint_init(Paint *p, const char col[3])
        /* If there's no brush, create one */
        brush = paint_brush(p);
        if (brush == NULL)
-               brush = BKE_brush_add("Brush");
+               brush = BKE_brush_add(G.main, "Brush");
        paint_brush_set(p, brush);
 
        memcpy(p->paint_cursor_col, col, 3);
index f6599cc9648392640f314630b69b4358fe6c10ca..f3391803294cc15a08389c62402f448a2ad7f066 100644 (file)
 #include "BKE_main.h"
 #include "BKE_speaker.h"
 
-void *BKE_speaker_add(const char *name)
+void *BKE_speaker_add(Main *bmain, const char *name)
 {
        Speaker *spk;
 
-       spk =  BKE_libblock_alloc(&G.main->speaker, ID_SPK, name);
+       spk =  BKE_libblock_alloc(&bmain->speaker, ID_SPK, name);
 
        spk->attenuation = 1.0f;
        spk->cone_angle_inner = 360.0f;
index a0f611a5a7b2709808dcd26c261dd3c763f1268b..3be9097ce82db6a2f118c7c5c4180b57f2832e3b 100644 (file)
@@ -171,9 +171,8 @@ void BKE_text_free(Text *text)
 #endif
 }
 
-Text *BKE_text_add(const char *name) 
+Text *BKE_text_add(Main *bmain, const char *name) 
 {
-       Main *bmain = G.main;
        Text *ta;
        TextLine *tmp;
        
@@ -363,9 +362,8 @@ int BKE_text_reload(Text *text)
        return 1;
 }
 
-Text *BKE_text_load(const char *file, const char *relpath)
+Text *BKE_text_load(Main *bmain, const char *file, const char *relpath)
 {
-       Main *bmain = G.main;
        FILE *fp;
        int i, llen, len;
        unsigned char *buffer;
index 2e909f11eaaa3f6222ad7b4f2b02b9dcc6bdefa2..55a0f3752a1b383e5c0fa0f121ac974369a7e668 100644 (file)
@@ -540,9 +540,8 @@ void tex_set_type(Tex *tex, int type)
 
 /* ------------------------------------------------------------------------- */
 
-Tex *add_texture(const char *name)
+Tex *add_texture(Main *bmain, const char *name)
 {
-       Main *bmain = G.main;
        Tex *tex;
 
        tex = BKE_libblock_alloc(&bmain->tex, ID_TE, name);
index ad101c41dc5ca960797e6fc71fabb6df9babf13d..206f829eaa83e4b4f82c95656a8a36a7121456e8 100644 (file)
@@ -79,9 +79,8 @@ void BKE_world_free(World *wrld)
        BKE_world_free_ex(wrld, TRUE);
 }
 
-World *add_world(const char *name)
+World *add_world(Main *bmain, const char *name)
 {
-       Main *bmain = G.main;
        World *wrld;
 
        wrld = BKE_libblock_alloc(&bmain->world, ID_WO, name);
index 077a716b17aa12db4e1c23f62382e122d70f8cb0..8a695ab4edb67fd80461ac7a60520b8d793621fb 100644 (file)
@@ -10027,7 +10027,7 @@ static void give_base_to_groups(Main *mainvar, Scene *scene)
                        Base *base;
                        
                        /* BKE_object_add(...) messes with the selection */
-                       Object *ob = BKE_object_add_only_object(OB_EMPTY, group->id.name+2);
+                       Object *ob = BKE_object_add_only_object(mainvar, OB_EMPTY, group->id.name+2);
                        ob->type = OB_EMPTY;
                        ob->lay = scene->lay;
                        
index 64832a1311f40b4134273c213de84a4116eb9c07..c99f939300e99686564806642f52834e2f8dd67d 100644 (file)
@@ -143,7 +143,7 @@ bAction *verify_adt_action(ID *id, short add)
        if ((adt->action == NULL) && (add)) {
                char actname[sizeof(id->name) - 2];
                BLI_snprintf(actname, sizeof(actname), "%sAction", id->name + 2);
-               adt->action = add_empty_action(actname);
+               adt->action = add_empty_action(G.main, actname);
        }
                
        /* return the action */
index 04815b9c33c0c836ade8f0d7c9cab69b3ad01052..b2c1b7fdcd0a26db2342f5dedf5284b321c0258f 100644 (file)
@@ -54,6 +54,7 @@
 #include "BKE_action.h"
 #include "BKE_armature.h"
 #include "BKE_depsgraph.h"
+#include "BKE_global.h"
 #include "BKE_idprop.h"
 #include "BKE_library.h"
 #include "BKE_object.h"
@@ -196,7 +197,7 @@ static bAction *poselib_init_new(Object *ob)
        /* init object's poselib action (unlink old one if there) */
        if (ob->poselib)
                id_us_min(&ob->poselib->id);
-       ob->poselib = add_empty_action("PoseLib");
+       ob->poselib = add_empty_action(G.main, "PoseLib");
        
        return ob->poselib;
 }
index e57e52d74b6927e2d73ac7ebb4b01627591556b4..e03a171da184321c8c28ad3e38158ac9536eb448 100644 (file)
@@ -661,11 +661,12 @@ static int reports_to_text_poll(bContext *C)
 static int reports_to_text_exec(bContext *C, wmOperator *UNUSED(op))
 {
        ReportList *reports = CTX_wm_reports(C);
+       Main *bmain = CTX_data_main(C);
        Text *txt;
        char *str;
        
        /* create new text-block to write to */
-       txt = BKE_text_add("Recent Reports");
+       txt = BKE_text_add(bmain, "Recent Reports");
        
        /* convert entire list to a display string, and add this to the text-block
         *      - if commandline debug option enabled, show debug reports too
@@ -803,7 +804,7 @@ static int editsource_text_edit(bContext *C, wmOperator *op,
        }
 
        if (text == NULL) {
-               text = BKE_text_load(filepath, bmain->name);
+               text = BKE_text_load(bmain, filepath, bmain->name);
        }
 
        if (text == NULL) {
index 35f85f3faee2cb950e209f3c9d8c0a348f406644..0a996c11f140bb0e0a45631d159cb3c2fe390318 100644 (file)
@@ -36,6 +36,7 @@
 
 #include "BKE_context.h"
 #include "BKE_depsgraph.h"
+#include "BKE_main.h"
 #include "BKE_mask.h"
 
 #include "DNA_scene_types.h"
@@ -261,9 +262,10 @@ int ED_mask_feather_find_nearest(const bContext *C, Mask *mask, float normal_co[
 Mask *ED_mask_new(bContext *C, const char *name)
 {
        ScrArea *sa = CTX_wm_area(C);
+       Main *bmain = CTX_data_main(C);
        Mask *mask;
 
-       mask = BKE_mask_new(name);
+       mask = BKE_mask_new(bmain, name);
 
        if (sa && sa->spacedata.first) {
                switch (sa->spacetype) {
index 8457b278c6c208ae1252c2e8bcc0a20376185770..3b2ddfe15ee0d489bfa118bd4dfe29db415bddca 100644 (file)
@@ -1558,7 +1558,7 @@ static int convert_exec(bContext *C, wmOperator *op)
                                mb = newob->data;
                                mb->id.us--;
 
-                               newob->data = BKE_mesh_add("Mesh");
+                               newob->data = BKE_mesh_add(bmain, "Mesh");
                                newob->type = OB_MESH;
 
                                me = newob->data;
index 7bf1a5db3b1c46c07b70f66a8018319bb675d7a9..9b683a1ba98ec5ddad6887ecdc81021806a6ce80 100644 (file)
@@ -311,7 +311,7 @@ static int group_create_exec(bContext *C, wmOperator *op)
        
        RNA_string_get(op->ptr, "name", name);
        
-       group = add_group(name);
+       group = add_group(bmain, name);
                
        CTX_DATA_BEGIN (C, Base *, base, selected_bases)
        {
@@ -348,12 +348,13 @@ static int group_add_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Scene *scene = CTX_data_scene(C);
        Object *ob = ED_object_context(C);
+       Main *bmain = CTX_data_main(C);
        Group *group;
 
        if (ob == NULL)
                return OPERATOR_CANCELLED;
 
-       group = add_group("Group");
+       group = add_group(bmain, "Group");
        add_to_group(group, ob, scene, NULL);
 
        WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
index fac835a414ab815e1fc0454d1904402bb16c7728..b2f53379090566569b4cdaa3d7bde393c4a41a3c 100644 (file)
@@ -45,6 +45,7 @@
 
 #include "BKE_context.h"
 #include "BKE_depsgraph.h"
+#include "BKE_global.h"
 #include "BKE_group.h"
 #include "BKE_object.h"
 #include "BKE_report.h"
@@ -87,7 +88,7 @@ void ED_rigidbody_con_add(wmOperator *op, Scene *scene, Object *ob, int type)
        }
        /* create constraint group if it doesn't already exits */
        if (rbw->constraints == NULL) {
-               rbw->constraints = add_group("RigidBodyConstraints");
+               rbw->constraints = add_group(G.main, "RigidBodyConstraints");
        }
        /* make rigidbody constraint settings */
        ob->rigidbody_constraint = BKE_rigidbody_create_constraint(scene, ob, type);
index 38ed903a161f0bf3d30b32fdc68b31163fabb77b..fa258c98567d27d37869c48a26d074e61779a45e 100644 (file)
@@ -46,6 +46,7 @@
 
 #include "BKE_context.h"
 #include "BKE_depsgraph.h"
+#include "BKE_global.h"
 #include "BKE_group.h"
 #include "BKE_object.h"
 #include "BKE_report.h"
@@ -113,7 +114,7 @@ void ED_rigidbody_ob_add(wmOperator *op, Scene *scene, Object *ob, int type)
                scene->rigidbody_world = rbw;
        }
        if (rbw->group == NULL) {
-               rbw->group = add_group("RigidBodyWorld");
+               rbw->group = add_group(G.main, "RigidBodyWorld");
        }
 
        /* make rigidbody object settings */
index 53e1f49d54421f9371a9c26daca5e746645c0175..e00db9b585013e5d564de8eb1026688bc61cff32 100644 (file)
@@ -367,6 +367,7 @@ static int new_material_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Scene *scene = CTX_data_scene(C);
        Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
+       Main *bmain = CTX_data_main(C);
        PointerRNA ptr, idptr;
        PropertyRNA *prop;
 
@@ -375,7 +376,7 @@ static int new_material_exec(bContext *C, wmOperator *UNUSED(op))
                ma = BKE_material_copy(ma);
        }
        else {
-               ma = BKE_material_add("Material");
+               ma = BKE_material_add(bmain, "Material");
 
                if (BKE_scene_use_new_shading_nodes(scene)) {
                        ED_node_shader_default(scene, &ma->id);
@@ -420,6 +421,7 @@ void MATERIAL_OT_new(wmOperatorType *ot)
 static int new_texture_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
+       Main *bmain = CTX_data_main(C);
        PointerRNA ptr, idptr;
        PropertyRNA *prop;
 
@@ -427,7 +429,7 @@ static int new_texture_exec(bContext *C, wmOperator *UNUSED(op))
        if (tex)
                tex = BKE_texture_copy(tex);
        else
-               tex = add_texture("Texture");
+               tex = add_texture(bmain, "Texture");
 
        /* hook into UI */
        uiIDContextProperty(C, &ptr, &prop);
@@ -467,6 +469,7 @@ static int new_world_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Scene *scene = CTX_data_scene(C);
        World *wo = CTX_data_pointer_get_type(C, "world", &RNA_World).data;
+       Main *bmain = CTX_data_main(C);
        PointerRNA ptr, idptr;
        PropertyRNA *prop;
 
@@ -475,7 +478,7 @@ static int new_world_exec(bContext *C, wmOperator *UNUSED(op))
                wo = BKE_world_copy(wo);
        }
        else {
-               wo = add_world("World");
+               wo = add_world(bmain, "World");
 
                if (BKE_scene_use_new_shading_nodes(scene)) {
                        ED_node_shader_default(scene, &wo->id);
index 618d545b08417768c5da23bcb80b60a69a7e26b9..408572c7979b05931baf762cf54098c70a0a5389 100644 (file)
@@ -62,11 +62,12 @@ static int brush_add_exec(bContext *C, wmOperator *UNUSED(op))
        /*int type = RNA_enum_get(op->ptr, "type");*/
        Paint *paint = paint_get_active_from_context(C);
        struct Brush *br = paint_brush(paint);
+       Main *bmain = CTX_data_main(C);
 
        if (br)
                br = BKE_brush_copy(br);
        else
-               br = BKE_brush_add("Brush");
+               br = BKE_brush_add(bmain, "Brush");
 
        paint_brush_set(paint, br);
 
@@ -272,7 +273,7 @@ static int brush_generic_tool_set(Main *bmain, Paint *paint, const int tool,
                brush = brush_tool_cycle(bmain, brush_orig, tool, tool_offset, ob_mode);
 
        if (!brush && brush_tool(brush_orig, tool_offset) != tool && create_missing) {
-               brush = BKE_brush_add(tool_name);
+               brush = BKE_brush_add(bmain, tool_name);
                brush_tool_set(brush, tool_offset, tool);
                brush->ob_mode = ob_mode;
                brush->toggle_brush = brush_orig;
index a80d425b90a125e1aa80eb804ffd715ea0a33d15..7e99e6c065dfed7ce87c4f3bf8ce46c0427fed19 100644 (file)
@@ -53,6 +53,7 @@
 #include "BKE_action.h"
 #include "BKE_fcurve.h"
 #include "BKE_global.h"
+#include "BKE_main.h"
 #include "BKE_nla.h"
 #include "BKE_context.h"
 #include "BKE_report.h"
@@ -104,8 +105,10 @@ static int act_new_exec(bContext *C, wmOperator *UNUSED(op))
                        action = BKE_action_copy(oldact);
                }
                else {
+                       Main *bmain = CTX_data_main(C);
+
                        /* just make a new (empty) action */
-                       action = add_empty_action("Action");
+                       action = add_empty_action(bmain, "Action");
                }
                
                /* when creating new ID blocks, use is already 1 (fake user), 
index cf4e76a842708fbf0b94ff69909c8c1ea8fe0aec..dfb69be6f188f5bce2b58836ca2d848a24db13ed 100644 (file)
@@ -160,6 +160,7 @@ static int open_exec(bContext *C, wmOperator *op)
 {
        SpaceClip *sc = CTX_wm_space_clip(C);
        bScreen *screen = CTX_wm_screen(C);
+       Main *bmain = CTX_data_main(C);
        PropertyPointerRNA *pprop;
        PointerRNA idptr;
        MovieClip *clip = NULL;
@@ -191,7 +192,7 @@ static int open_exec(bContext *C, wmOperator *op)
 
        errno = 0;
 
-       clip = BKE_movieclip_file_add(str);
+       clip = BKE_movieclip_file_add(bmain, str);
 
        if (!clip) {
                if (op->customdata)
index 8bb51edde02f5fd3db5c456c9f6850b5e3c826e5..2d2d29d9eaa61fc7e15c5a2846ec7c0e95f22b60 100644 (file)
@@ -1716,6 +1716,7 @@ static int image_new_exec(bContext *C, wmOperator *op)
        Scene *scene;
        Object *obedit;
        Image *ima;
+       Main *bmain;
        PointerRNA ptr, idptr;
        PropertyRNA *prop;
        char name[MAX_ID_NAME - 2];
@@ -1726,6 +1727,7 @@ static int image_new_exec(bContext *C, wmOperator *op)
        sima = CTX_wm_space_image(C);
        scene = CTX_data_scene(C);
        obedit = CTX_data_edit_object(C);
+       bmain = CTX_data_main(C);
 
        RNA_string_get(op->ptr, "name", name);
        width = RNA_int_get(op->ptr, "width");
@@ -1738,7 +1740,7 @@ static int image_new_exec(bContext *C, wmOperator *op)
        if (!alpha)
                color[3] = 1.0f;
 
-       ima = BKE_image_add_generated(width, height, name, alpha ? 32 : 24, floatbuf, gen_type, color);
+       ima = BKE_image_add_generated(bmain, width, height, name, alpha ? 32 : 24, floatbuf, gen_type, color);
 
        if (!ima)
                return OPERATOR_CANCELLED;
index b47be150417afea835bb15684c565604d62b176a..22631568d03964a4f724d71a5ebe4d63e2bd5c39 100644 (file)
@@ -441,6 +441,7 @@ static int new_node_tree_exec(bContext *C, wmOperator *op)
 {
        SpaceNode *snode;
        bNodeTree *ntree;
+       Main *bmain;
        PointerRNA ptr, idptr;
        PropertyRNA *prop;
        int treetype;
@@ -448,6 +449,7 @@ static int new_node_tree_exec(bContext *C, wmOperator *op)
 
        /* retrieve state */
        snode = CTX_wm_space_node(C);
+       bmain = CTX_data_main(C);
 
        if (RNA_struct_property_is_set(op->ptr, "type"))
                treetype = RNA_enum_get(op->ptr, "type");
@@ -457,7 +459,7 @@ static int new_node_tree_exec(bContext *C, wmOperator *op)
        if (RNA_struct_property_is_set(op->ptr, "name"))
                RNA_string_get(op->ptr, "name", treename);
 
-       ntree = ntreeAddTree(treename, treetype, 0);
+       ntree = ntreeAddTree(bmain, treename, treetype, 0);
        if (!ntree)
                return OPERATOR_CANCELLED;
 
index 321eaa32e80a3146a7afdd852a553c321d8edffe..fb4e4f62e52823867e2a3f9ceda1f34012e81883 100644 (file)
@@ -328,7 +328,7 @@ void ED_node_shader_default(Scene *scene, ID *id)
        int output_type, shader_type;
        float color[3], strength = 1.0f;
        
-       ntree = ntreeAddTree("Shader Nodetree", NTREE_SHADER, 0);
+       ntree = ntreeAddTree(G.main, "Shader Nodetree", NTREE_SHADER, 0);
 
        switch (GS(id->name)) {
                case ID_MA:
@@ -424,7 +424,7 @@ void ED_node_composit_default(Scene *sce)
                return;
        }
        
-       sce->nodetree = ntreeAddTree("Compositing Nodetree", NTREE_COMPOSIT, 0);
+       sce->nodetree = ntreeAddTree(G.main, "Compositing Nodetree", NTREE_COMPOSIT, 0);
 
        sce->nodetree->chunksize = 256;
        sce->nodetree->edit_quality = NTREE_QUALITY_HIGH;
@@ -468,7 +468,7 @@ void ED_node_texture_default(Tex *tx)
                return;
        }
        
-       tx->nodetree = ntreeAddTree("Texture Nodetree", NTREE_TEXTURE, 0);
+       tx->nodetree = ntreeAddTree(G.main, "Texture Nodetree", NTREE_TEXTURE, 0);
        
        ntemp.type = TEX_NODE_OUTPUT;
        out = nodeAddNode(tx->nodetree, &ntemp);
index 4dd9c89375d64fb8a29efd58c1ab1cbe1e37bfc8..7572ca04a3327f88d6aca5906e13fa745b4ae471 100644 (file)
@@ -1039,7 +1039,7 @@ static bNode *node_group_make_from_selected(bNodeTree *ntree)
        node_get_selected_minmax(ntree, NULL, min, max);
 
        /* new nodetree */
-       ngroup = ntreeAddTree("NodeGroup", ntree->type, NODE_GROUP);
+       ngroup = ntreeAddTree(G.main, "NodeGroup", ntree->type, NODE_GROUP);
 
        /* make group node */
        ntemp.type = NODE_GROUP;
index e82917feb2122b363c42482d09620078e53666e6..e92d93485a108bc654d0ebf7a7b546e2818d2bf1 100644 (file)
@@ -136,7 +136,7 @@ static void do_node_add_group(bContext *C, void *UNUSED(arg), int event)
                ntemp.type = -event;
                switch (ntemp.type) {
                        case NODE_GROUP:
-                               ntemp.ngroup = ntreeAddTree("Group", snode->treetype, ntemp.type);
+                               ntemp.ngroup = ntreeAddTree(bmain, "Group", snode->treetype, ntemp.type);
                                break;
                        default:
                                ntemp.ngroup = NULL;
index 21966ef614cba58588dc18433f089b6f33d43201..1f209f90007ef9924050d38ee3834cd37822240f 100644 (file)
@@ -161,11 +161,12 @@ void text_update_edited(Text *text)
 static int text_new_exec(bContext *C, wmOperator *UNUSED(op))
 {
        SpaceText *st = CTX_wm_space_text(C);
+       Main *bmain = CTX_data_main(C);
        Text *text;
        PointerRNA ptr, idptr;
        PropertyRNA *prop;
 
-       text = BKE_text_add("Text");
+       text = BKE_text_add(bmain, "Text");
 
        /* hook into UI */
        uiIDContextProperty(C, &ptr, &prop);
@@ -226,6 +227,7 @@ static int text_open_cancel(bContext *UNUSED(C), wmOperator *op)
 static int text_open_exec(bContext *C, wmOperator *op)
 {
        SpaceText *st = CTX_wm_space_text(C);
+       Main *bmain = CTX_data_main(C);
        Text *text;
        PropertyPointerRNA *pprop;
        PointerRNA idptr;
@@ -234,7 +236,7 @@ static int text_open_exec(bContext *C, wmOperator *op)
 
        RNA_string_get(op->ptr, "filepath", str);
 
-       text = BKE_text_load(str, G.main->name);
+       text = BKE_text_load(bmain, str, G.main->name);
 
        if (!text) {
                if (op->customdata) MEM_freeN(op->customdata);
index 76947d856f87271a0d1ee1d3f8b64a672f4939b0..d908e84430b2c43608f145a3e082fc2b259835d6 100644 (file)
@@ -398,6 +398,8 @@ PointerRNA rna_pointer_inherit_refine(struct PointerRNA *ptr, struct StructRNA *
 int rna_parameter_size(struct PropertyRNA *parm);
 int rna_parameter_size_alloc(struct PropertyRNA *parm);
 
+struct Mesh *rna_Main_meshes_new_from_object(struct Main *bmain, struct ReportList *reports, struct Scene *sce, struct Object *ob, int apply_modifiers, int settings);
+
 /* XXX, these should not need to be defined here~! */
 struct MTex *rna_mtex_texture_slots_add(struct ID *self, struct bContext *C, struct ReportList *reports);
 struct MTex *rna_mtex_texture_slots_create(struct ID *self, struct bContext *C, struct ReportList *reports, int index);
index e9ed3aa8682520276499aee20314c0f348159a65..ab94b88e3d7df034ee8d209508b5af8ca9603335 100644 (file)
@@ -34,6 +34,7 @@
 #include <errno.h>
 
 #include "DNA_ID.h"
+#include "DNA_modifier_types.h"
 
 #include "BLI_path_util.h"
 
@@ -48,6 +49,8 @@
 #include "BKE_main.h"
 #include "BKE_camera.h"
 #include "BKE_curve.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_displist.h"
 #include "BKE_mesh.h"
 #include "BKE_armature.h"
 #include "BKE_lamp.h"
 
 #include "BLF_translation.h"
 
-static Camera *rna_Main_cameras_new(Main *UNUSED(bmain), const char *name)
+static Camera *rna_Main_cameras_new(Main *bmain, const char *name)
 {
-       ID *id = BKE_camera_add(name);
+       ID *id = BKE_camera_add(bmain, name);
        id_us_min(id);
        return (Camera *)id;
 }
-static void rna_Main_cameras_remove(Main *UNUSED(bmain), ReportList *reports, PointerRNA *camera_ptr)
+static void rna_Main_cameras_remove(Main *bmain, ReportList *reports, PointerRNA *camera_ptr)
 {
        Camera *camera = camera_ptr->data;
        if (ID_REAL_USERS(camera) <= 0) {
-               BKE_libblock_free(&G.main->camera, camera);
+               BKE_libblock_free(&bmain->camera, camera);
                RNA_POINTER_INVALIDATE(camera_ptr);
        }
        else {
@@ -144,7 +147,7 @@ static void rna_Main_scenes_remove(Main *bmain, bContext *C, ReportList *reports
        }
 }
 
-static Object *rna_Main_objects_new(Main *UNUSED(bmain), ReportList *reports, const char *name, ID *data)
+static Object *rna_Main_objects_new(Main *bmain, ReportList *reports, const char *name, ID *data)
 {
        Object *ob;
        int type = OB_EMPTY;
@@ -189,7 +192,7 @@ static Object *rna_Main_objects_new(Main *UNUSED(bmain), ReportList *reports, co
                id_us_plus(data);
        }
 
-       ob = BKE_object_add_only_object(type, name);
+       ob = BKE_object_add_only_object(bmain, type, name);
        id_us_min(&ob->id);
 
        ob->data = data;
@@ -198,12 +201,12 @@ static Object *rna_Main_objects_new(Main *UNUSED(bmain), ReportList *reports, co
        return ob;
 }
 
-static void rna_Main_objects_remove(Main *UNUSED(bmain), ReportList *reports, PointerRNA *object_ptr)
+static void rna_Main_objects_remove(Main *bmain, ReportList *reports, PointerRNA *object_ptr)
 {
        Object *object = object_ptr->data;
        if (ID_REAL_USERS(object) <= 0) {
                BKE_object_unlink(object); /* needed or ID pointers to this are not cleared */
-               BKE_libblock_free(&G.main->object, object);
+               BKE_libblock_free(&bmain->object, object);
                RNA_POINTER_INVALIDATE(object_ptr);
        }
        else {
@@ -212,17 +215,17 @@ static void rna_Main_objects_remove(Main *UNUSED(bmain), ReportList *reports, Po
        }
 }
 
-static Material *rna_Main_materials_new(Main *UNUSED(bmain), const char *name)
+static Material *rna_Main_materials_new(Main *bmain, const char *name)
 {
-       ID *id = (ID *)BKE_material_add(name);
+       ID *id = (ID *)BKE_material_add(bmain, name);
        id_us_min(id);
        return (Material *)id;
 }
-static void rna_Main_materials_remove(Main *UNUSED(bmain), ReportList *reports, PointerRNA *material_ptr)
+static void rna_Main_materials_remove(Main *bmain, ReportList *reports, PointerRNA *material_ptr)
 {
        Material *material = material_ptr->data;
        if (ID_REAL_USERS(material) <= 0) {
-               BKE_libblock_free(&G.main->mat, material);
+               BKE_libblock_free(&bmain->mat, material);
                RNA_POINTER_INVALIDATE(material_ptr);
        }
        else {
@@ -231,18 +234,18 @@ static void rna_Main_materials_remove(Main *UNUSED(bmain), ReportList *reports,
        }
 }
 
-static bNodeTree *rna_Main_nodetree_new(Main *UNUSED(bmain), const char *name, int type)
+static bNodeTree *rna_Main_nodetree_new(Main *bmain, const char *name, int type)
 {
-       bNodeTree *tree = ntreeAddTree(name, type, NODE_GROUP);
+       bNodeTree *tree = ntreeAddTree(bmain, name, type, NODE_GROUP);
 
        id_us_min(&tree->id);
        return tree;
 }
-static void rna_Main_nodetree_remove(Main *UNUSED(bmain), ReportList *reports, PointerRNA *tree_ptr)
+static void rna_Main_nodetree_remove(Main *bmain, ReportList *reports, PointerRNA *tree_ptr)
 {
        bNodeTree *tree = tree_ptr->data;
        if (ID_REAL_USERS(tree) <= 0) {
-               BKE_libblock_free(&G.main->nodetree, tree);
+               BKE_libblock_free(&bmain->nodetree, tree);
                RNA_POINTER_INVALIDATE(tree_ptr);
        }
        else {
@@ -251,18 +254,212 @@ static void rna_Main_nodetree_remove(Main *UNUSED(bmain), ReportList *reports, P
        }
 }
 
-static Mesh *rna_Main_meshes_new(Main *UNUSED(bmain), const char *name)
+static Mesh *rna_Main_meshes_new(Main *bmain, const char *name)
 {
-       Mesh *me = BKE_mesh_add(name);
+       Mesh *me = BKE_mesh_add(bmain, name);
        id_us_min(&me->id);
        return me;
 }
-static void rna_Main_meshes_remove(Main *UNUSED(bmain), ReportList *reports, PointerRNA *mesh_ptr)
+
+/* copied from Mesh_getFromObject and adapted to RNA interface */
+/* settings: 1 - preview, 2 - render */
+Mesh *rna_Main_meshes_new_from_object(Main *bmain, ReportList *reports, Scene *sce, Object *ob, int apply_modifiers, int settings)
 {
-       Mesh *mesh = mesh_ptr->data;
+       Mesh *tmpmesh;
+       Curve *tmpcu = NULL, *copycu;
+       Object *tmpobj = NULL;
+       int render = settings == eModifierMode_Render, i;
+       int cage = !apply_modifiers;
+
+       /* perform the mesh extraction based on type */
+       switch (ob->type) {
+               case OB_FONT:
+               case OB_CURVE:
+               case OB_SURF:
+               {
+                       ListBase dispbase = {NULL, NULL};
+                       DerivedMesh *derivedFinal = NULL;
+                       int uv_from_orco;
+
+                       /* copies object and modifiers (but not the data) */
+                       tmpobj = BKE_object_copy_ex(bmain, ob, TRUE);
+                       tmpcu = (Curve *)tmpobj->data;
+                       tmpcu->id.us--;
+
+                       /* if getting the original caged mesh, delete object modifiers */
+                       if (cage)
+                               BKE_object_free_modifiers(tmpobj);
+
+                       /* copies the data */
+                       copycu = tmpobj->data = BKE_curve_copy((Curve *) ob->data);
+
+                       /* temporarily set edit so we get updates from edit mode, but
+                        * also because for text datablocks copying it while in edit
+                        * mode gives invalid data structures */
+                       copycu->editfont = tmpcu->editfont;
+                       copycu->editnurb = tmpcu->editnurb;
 
+                       /* get updated display list, and convert to a mesh */
+                       BKE_displist_make_curveTypes_forRender(sce, tmpobj, &dispbase, &derivedFinal, FALSE);
+
+                       copycu->editfont = NULL;
+                       copycu->editnurb = NULL;
+
+                       tmpobj->derivedFinal = derivedFinal;
+
+                       /* convert object type to mesh */
+                       uv_from_orco = (tmpcu->flag & CU_UV_ORCO) != 0;
+                       BKE_mesh_from_nurbs_displist(tmpobj, &dispbase, uv_from_orco);
+
+                       tmpmesh = tmpobj->data;
+
+                       BKE_displist_free(&dispbase);
+
+                       /* BKE_mesh_from_nurbs changes the type to a mesh, check it worked */
+                       if (tmpobj->type != OB_MESH) {
+                               BKE_libblock_free_us(&(G.main->object), tmpobj);
+                               BKE_report(reports, RPT_ERROR, "Cannot convert curve to mesh (does the curve have any segments?)");
+                               return NULL;
+                       }
+
+                       BKE_libblock_free_us(&bmain->object, tmpobj);
+                       break;
+               }
+
+               case OB_MBALL:
+               {
+                       /* metaballs don't have modifiers, so just convert to mesh */
+                       Object *basis_ob = BKE_mball_basis_find(sce, ob);
+                       /* todo, re-generatre for render-res */
+                       /* metaball_polygonize(scene, ob) */
+
+                       if (ob != basis_ob)
+                               return NULL;  /* only do basis metaball */
+
+                       tmpmesh = BKE_mesh_add(bmain, "Mesh");
+                       /* BKE_mesh_add gives us a user count we don't need */
+                       tmpmesh->id.us--;
+
+                       if (render) {
+                               ListBase disp = {NULL, NULL};
+                               BKE_displist_make_mball_forRender(sce, ob, &disp);
+                               BKE_mesh_from_metaball(&disp, tmpmesh);
+                               BKE_displist_free(&disp);
+                       }
+                       else
+                               BKE_mesh_from_metaball(&ob->disp, tmpmesh);
+
+                       break;
+
+               }
+               case OB_MESH:
+                       /* copies object and modifiers (but not the data) */
+                       if (cage) {
+                               /* copies the data */
+                               tmpmesh = BKE_mesh_copy_ex(bmain, ob->data);
+                               /* if not getting the original caged mesh, get final derived mesh */
+                       }
+                       else {
+                               /* Make a dummy mesh, saves copying */
+                               DerivedMesh *dm;
+                               /* CustomDataMask mask = CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL; */
+                               CustomDataMask mask = CD_MASK_MESH; /* this seems more suitable, exporter,
+                                                                * for example, needs CD_MASK_MDEFORMVERT */
+
+                               /* Write the display mesh into the dummy mesh */
+                               if (render)
+                                       dm = mesh_create_derived_render(sce, ob, mask);
+                               else
+                                       dm = mesh_create_derived_view(sce, ob, mask);
+
+                               tmpmesh = BKE_mesh_add(bmain, "Mesh");
+                               DM_to_mesh(dm, tmpmesh, ob);
+                               dm->release(dm);
+                       }
+
+                       /* BKE_mesh_add/copy gives us a user count we don't need */
+                       tmpmesh->id.us--;
+
+                       break;
+               default:
+                       BKE_report(reports, RPT_ERROR, "Object does not have geometry data");
+                       return NULL;
+       }
+
+       /* Copy materials to new mesh */
+       switch (ob->type) {
+               case OB_SURF:
+               case OB_FONT:
+               case OB_CURVE:
+                       tmpmesh->totcol = tmpcu->totcol;
+
+                       /* free old material list (if it exists) and adjust user counts */
+                       if (tmpcu->mat) {
+                               for (i = tmpcu->totcol; i-- > 0; ) {
+                                       /* are we an object material or data based? */
+
+                                       tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : tmpcu->mat[i];
+
+                                       if (tmpmesh->mat[i]) {
+                                               tmpmesh->mat[i]->id.us++;
+                                       }
+                               }
+                       }
+                       break;
+
+#if 0
+               /* Crashes when assigning the new material, not sure why */
+               case OB_MBALL:
+                       tmpmb = (MetaBall *)ob->data;
+                       tmpmesh->totcol = tmpmb->totcol;
+
+                       /* free old material list (if it exists) and adjust user counts */
+                       if (tmpmb->mat) {
+                               for (i = tmpmb->totcol; i-- > 0; ) {
+                                       tmpmesh->mat[i] = tmpmb->mat[i]; /* CRASH HERE ??? */
+                                       if (tmpmesh->mat[i]) {
+                                               tmpmb->mat[i]->id.us++;
+                                       }
+                               }
+                       }
+                       break;
+#endif
+
+               case OB_MESH:
+                       if (!cage) {
+                               Mesh *origmesh = ob->data;
+                               tmpmesh->flag = origmesh->flag;
+                               tmpmesh->mat = MEM_dupallocN(origmesh->mat);
+                               tmpmesh->totcol = origmesh->totcol;
+                               tmpmesh->smoothresh = origmesh->smoothresh;
+                               if (origmesh->mat) {
+                                       for (i = origmesh->totcol; i-- > 0; ) {
+                                               /* are we an object material or data based? */
+                                               tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : origmesh->mat[i];
+
+                                               if (tmpmesh->mat[i]) {
+                                                       tmpmesh->mat[i]->id.us++;
+                                               }
+                                       }
+                               }
+                       }
+                       break;
+       } /* end copy materials */
+
+       /* cycles and exporters rely on this still */
+       BKE_mesh_tessface_ensure(tmpmesh);
+
+       /* make sure materials get updated in objects */
+       test_object_materials(&tmpmesh->id);
+
+       return tmpmesh;
+}
+
+static void rna_Main_meshes_remove(Main *bmain, ReportList *reports, PointerRNA *mesh_ptr)
+{
+       Mesh *mesh = mesh_ptr->data;
        if (ID_REAL_USERS(mesh) <= 0) {
-               BKE_libblock_free(&G.main->mesh, mesh);
+               BKE_libblock_free(&bmain->mesh, mesh);
                RNA_POINTER_INVALIDATE(mesh_ptr);
        }
        else {
@@ -271,18 +468,18 @@ static void rna_Main_meshes_remove(Main *UNUSED(bmain), ReportList *reports, Poi
        }
 }
 
-static Lamp *rna_Main_lamps_new(Main *UNUSED(bmain), const char *name, int type)
+static Lamp *rna_Main_lamps_new(Main *bmain, const char *name, int type)
 {
-       Lamp *lamp = BKE_lamp_add(name);
+       Lamp *lamp = BKE_lamp_add(bmain, name);
        lamp->type = type;
        id_us_min(&lamp->id);
        return lamp;
 }
-static void rna_Main_lamps_remove(Main *UNUSED(bmain), ReportList *reports, PointerRNA *lamp_ptr)
+static void rna_Main_lamps_remove(Main *bmain, ReportList *reports, PointerRNA *lamp_ptr)
 {
        Lamp *lamp = lamp_ptr->data;
        if (ID_REAL_USERS(lamp) <= 0) {
-               BKE_libblock_free(&G.main->lamp, lamp);
+               BKE_libblock_free(&bmain->lamp, lamp);
                RNA_POINTER_INVALIDATE(lamp_ptr);
        }
        else {
@@ -291,19 +488,19 @@ static void rna_Main_lamps_remove(Main *UNUSED(bmain), ReportList *reports, Poin
        }
 }
 
-static Image *rna_Main_images_new(Main *UNUSED(bmain), const char *name, int width, int height, int alpha, int float_buffer)
+static Image *rna_Main_images_new(Main *bmain, const char *name, int width, int height, int alpha, int float_buffer)
 {
        float color[4] = {0.0, 0.0, 0.0, 1.0};
-       Image *image = BKE_image_add_generated(width, height, name, alpha ? 32 : 24, float_buffer, 0, color);
+       Image *image = BKE_image_add_generated(bmain, width, height, name, alpha ? 32 : 24, float_buffer, 0, color);
        id_us_min(&image->id);
        return image;
 }
-static Image *rna_Main_images_load(Main *UNUSED(bmain), ReportList *reports, const char *filepath)
+static Image *rna_Main_images_load(Main *bmain, ReportList *reports, const char *filepath)
 {
        Image *ima;
 
        errno = 0;
-       ima = BKE_image_load(filepath);
+       ima = BKE_image_load(bmain, filepath);
 
        if (!ima) {
                BKE_reportf(reports, RPT_ERROR, "Cannot read '%s': %s", filepath,
@@ -312,11 +509,11 @@ static Image *rna_Main_images_load(Main *UNUSED(bmain), ReportList *reports, con
 
        return ima;
 }
-static void rna_Main_images_remove(Main *UNUSED(bmain), ReportList *reports, PointerRNA *image_ptr)
+static void rna_Main_images_remove(Main *bmain, ReportList *reports, PointerRNA *image_ptr)
 {
        Image *image = image_ptr->data;
        if (ID_REAL_USERS(image) <= 0) {
-               BKE_libblock_free(&G.main->image, image);
+               BKE_libblock_free(&bmain->image, image);
                RNA_POINTER_INVALIDATE(image_ptr);
        }
        else {
@@ -325,17 +522,17 @@ static void rna_Main_images_remove(Main *UNUSED(bmain), ReportList *reports, Poi
        }
 }
 
-static Lattice *rna_Main_lattices_new(Main *UNUSED(bmain), const char *name)
+static Lattice *rna_Main_lattices_new(Main *bmain, const char *name)
 {
-       Lattice *lt = BKE_lattice_add(name);
+       Lattice *lt = BKE_lattice_add(bmain, name);
        id_us_min(&lt->id);
        return lt;
 }
-static void rna_Main_lattices_remove(Main *UNUSED(bmain), ReportList *reports, PointerRNA *lt_ptr)
+static void rna_Main_lattices_remove(Main *bmain, ReportList *reports, PointerRNA *lt_ptr)
 {
        Lattice *lt = lt_ptr->data;
        if (ID_REAL_USERS(lt) <= 0) {
-               BKE_libblock_free(&G.main->latt, lt);
+               BKE_libblock_free(&bmain->latt, lt);
                RNA_POINTER_INVALIDATE(lt_ptr);
        }
        else {
@@ -344,17 +541,17 @@ static void rna_Main_lattices_remove(Main *UNUSED(bmain), ReportList *reports, P
        }
 }
 
-static Curve *rna_Main_curves_new(Main *UNUSED(bmain), const char *name, int type)
+static Curve *rna_Main_curves_new(Main *bmain, const char *name, int type)
 {
-       Curve *cu = BKE_curve_add(name, type);
+       Curve *cu = BKE_curve_add(bmain, name, type);
        id_us_min(&cu->id);
        return cu;
 }
-static void rna_Main_curves_remove(Main *UNUSED(bmain), ReportList *reports, PointerRNA *cu_ptr)
+static void rna_Main_curves_remove(Main *bmain, ReportList *reports, PointerRNA *cu_ptr)
 {
        Curve *cu = cu_ptr->data;
        if (ID_REAL_USERS(cu) <= 0) {
-               BKE_libblock_free(&G.main->curve, cu);
+               BKE_libblock_free(&bmain->curve, cu);
                RNA_POINTER_INVALIDATE(cu_ptr);
        }
        else {
@@ -363,17 +560,17 @@ static void rna_Main_curves_remove(Main *UNUSED(bmain), ReportList *reports, Poi
        }
 }
 
-static MetaBall *rna_Main_metaballs_new(Main *UNUSED(bmain), const char *name)
+static MetaBall *rna_Main_metaballs_new(Main *bmain, const char *name)
 {
-       MetaBall *mb = BKE_mball_add(name);
+       MetaBall *mb = BKE_mball_add(bmain, name);
        id_us_min(&mb->id);
        return mb;
 }
-static void rna_Main_metaballs_remove(Main *UNUSED(bmain), ReportList *reports, PointerRNA *mb_ptr)
+static void rna_Main_metaballs_remove(Main *bmain, ReportList *reports, PointerRNA *mb_ptr)
 {
        MetaBall *mb = mb_ptr->data;
        if (ID_REAL_USERS(mb) <= 0) {
-               BKE_libblock_free(&G.main->mball, mb);
+               BKE_libblock_free(&bmain->mball, mb);
                RNA_POINTER_INVALIDATE(mb_ptr);
        }
        else {
@@ -409,18 +606,18 @@ static void rna_Main_fonts_remove(Main *bmain, ReportList *reports, PointerRNA *
        }
 }
 
-static Tex *rna_Main_textures_new(Main *UNUSED(bmain), const char *name, int type)
+static Tex *rna_Main_textures_new(Main *bmain, const char *name, int type)
 {
-       Tex *tex = add_texture(name);
+       Tex *tex = add_texture(bmain, name);
        tex_set_type(tex, type);
        id_us_min(&tex->id);
        return tex;
 }
-static void rna_Main_textures_remove(Main *UNUSED(bmain), ReportList *reports, PointerRNA *tex_ptr)
+static void rna_Main_textures_remove(Main *bmain, ReportList *reports, PointerRNA *tex_ptr)
 {
        Tex *tex = tex_ptr->data;
        if (ID_REAL_USERS(tex) <= 0) {
-               BKE_libblock_free(&G.main->tex, tex);
+               BKE_libblock_free(&bmain->tex, tex);
                RNA_POINTER_INVALIDATE(tex_ptr);
        }
        else {
@@ -429,17 +626,17 @@ static void rna_Main_textures_remove(Main *UNUSED(bmain), ReportList *reports, P
        }
 }
 
-static Brush *rna_Main_brushes_new(Main *UNUSED(bmain), const char *name)
+static Brush *rna_Main_brushes_new(Main *bmain, const char *name)
 {
-       Brush *brush = BKE_brush_add(name);
+       Brush *brush = BKE_brush_add(bmain, name);
        id_us_min(&brush->id);
        return brush;
 }
-static void rna_Main_brushes_remove(Main *UNUSED(bmain), ReportList *reports, PointerRNA *brush_ptr)
+static void rna_Main_brushes_remove(Main *bmain, ReportList *reports, PointerRNA *brush_ptr)
 {
        Brush *brush = brush_ptr->data;
        if (ID_REAL_USERS(brush) <= 0) {
-               BKE_libblock_free(&G.main->brush, brush);
+               BKE_libblock_free(&bmain->brush, brush);
                RNA_POINTER_INVALIDATE(brush_ptr);
        }
        else {
@@ -448,17 +645,17 @@ static void rna_Main_brushes_remove(Main *UNUSED(bmain), ReportList *reports, Po
        }
 }
 
-static World *rna_Main_worlds_new(Main *UNUSED(bmain), const char *name)
+static World *rna_Main_worlds_new(Main *bmain, const char *name)
 {
-       World *world = add_world(name);
+       World *world = add_world(bmain, name);
        id_us_min(&world->id);
        return world;
 }
-static void rna_Main_worlds_remove(Main *UNUSED(bmain), ReportList *reports, PointerRNA *world_ptr)
+static void rna_Main_worlds_remove(Main *bmain, ReportList *reports, PointerRNA *world_ptr)
 {
        Group *world = world_ptr->data;
        if (ID_REAL_USERS(world) <= 0) {
-               BKE_libblock_free(&G.main->world, world);
+               BKE_libblock_free(&bmain->world, world);
                RNA_POINTER_INVALIDATE(world_ptr);
        }
        else {
@@ -467,29 +664,29 @@ static void rna_Main_worlds_remove(Main *UNUSED(bmain), ReportList *reports, Poi
        }
 }
 
-static Group *rna_Main_groups_new(Main *UNUSED(bmain), const char *name)
+static Group *rna_Main_groups_new(Main *bmain, const char *name)
 {
-       return add_group(name);
+       return add_group(bmain, name);
 }
-static void rna_Main_groups_remove(Main *UNUSED(bmain), PointerRNA *group_ptr)
+static void rna_Main_groups_remove(Main *bmain, PointerRNA *group_ptr)
 {
        Group *group = group_ptr->data;
        BKE_group_unlink(group);
-       BKE_libblock_free(&G.main->group, group);
+       BKE_libblock_free(&bmain->group, group);
        RNA_POINTER_INVALIDATE(group_ptr);
 }
 
-static Speaker *rna_Main_speakers_new(Main *UNUSED(bmain), const char *name)
+static Speaker *rna_Main_speakers_new(Main *bmain, const char *name)
 {
-       Speaker *speaker = BKE_speaker_add(name);
+       Speaker *speaker = BKE_speaker_add(bmain, name);
        id_us_min(&speaker->id);
        return speaker;
 }
-static void rna_Main_speakers_remove(Main *UNUSED(bmain), ReportList *reports, PointerRNA *speaker_ptr)
+static void rna_Main_speakers_remove(Main *bmain, ReportList *reports, PointerRNA *speaker_ptr)
 {
        Speaker *speaker = speaker_ptr->data;
        if (ID_REAL_USERS(speaker) <= 0) {
-               BKE_libblock_free(&G.main->speaker, speaker);
+               BKE_libblock_free(&bmain->speaker, speaker);
                RNA_POINTER_INVALIDATE(speaker_ptr);
        }
        else {
@@ -498,15 +695,15 @@ static void rna_Main_speakers_remove(Main *UNUSED(bmain), ReportList *reports, P
        }
 }
 
-static Text *rna_Main_texts_new(Main *UNUSED(bmain), const char *name)
+static Text *rna_Main_texts_new(Main *bmain, const char *name)
 {
-       return BKE_text_add(name);
+       return BKE_text_add(bmain, name);
 }
-static void rna_Main_texts_remove(Main *UNUSED(bmain), PointerRNA *text_ptr)
+static void rna_Main_texts_remove(Main *bmain, PointerRNA *text_ptr)
 {
        Text *text = text_ptr->data;
-       BKE_text_unlink(G.main, text);
-       BKE_libblock_free(&G.main->text, text);
+       BKE_text_unlink(bmain, text);
+       BKE_libblock_free(&bmain->text, text);
        RNA_POINTER_INVALIDATE(text_ptr);
 }
 
@@ -515,7 +712,7 @@ static Text *rna_Main_texts_load(Main *bmain, ReportList *reports, const char *f
        Text *txt;
 
        errno = 0;
-       txt = BKE_text_load(filepath, bmain->name);
+       txt = BKE_text_load(bmain, filepath, bmain->name);
 
        if (!txt)
                BKE_reportf(reports, RPT_ERROR, "Cannot read '%s': %s", filepath,
@@ -524,17 +721,17 @@ static Text *rna_Main_texts_load(Main *bmain, ReportList *reports, const char *f
        return txt;
 }
 
-static bArmature *rna_Main_armatures_new(Main *UNUSED(bmain), const char *name)
+static bArmature *rna_Main_armatures_new(Main *bmain, const char *name)
 {
-       bArmature *arm = BKE_armature_add(name);
+       bArmature *arm = BKE_armature_add(bmain, name);
        id_us_min(&arm->id);
        return arm;
 }
-static void rna_Main_armatures_remove(Main *UNUSED(bmain), ReportList *reports, PointerRNA *arm_ptr)
+static void rna_Main_armatures_remove(Main *bmain, ReportList *reports, PointerRNA *arm_ptr)
 {
        bArmature *arm = arm_ptr->data;
        if (ID_REAL_USERS(arm) <= 0) {
-               BKE_libblock_free(&G.main->armature, arm);
+               BKE_libblock_free(&bmain->armature, arm);
                RNA_POINTER_INVALIDATE(arm_ptr);
        }
        else {
@@ -543,18 +740,18 @@ static void rna_Main_armatures_remove(Main *UNUSED(bmain), ReportList *reports,
        }
 }
 
-static bAction *rna_Main_actions_new(Main *UNUSED(bmain), const char *name)
+static bAction *rna_Main_actions_new(Main *bmain, const char *name)
 {
-       bAction *act = add_empty_action(name);
+       bAction *act = add_empty_action(bmain, name);
        id_us_min(&act->id);
        act->id.flag &= ~LIB_FAKEUSER;
        return act;
 }
-static void rna_Main_actions_remove(Main *UNUSED(bmain), ReportList *reports, PointerRNA *act_ptr)
+static void rna_Main_actions_remove(Main *bmain, ReportList *reports, PointerRNA *act_ptr)
 {
        bAction *act = act_ptr->data;
        if (ID_REAL_USERS(act) <= 0) {
-               BKE_libblock_free(&G.main->action, act);
+               BKE_libblock_free(&bmain->action, act);
                RNA_POINTER_INVALIDATE(act_ptr);
        }
        else {
@@ -582,12 +779,12 @@ static void rna_Main_particles_remove(Main *bmain, ReportList *reports, PointerR
        }
 }
 
-static MovieClip *rna_Main_movieclip_load(Main *UNUSED(bmain), ReportList *reports, const char *filepath)
+static MovieClip *rna_Main_movieclip_load(Main *bmain, ReportList *reports, const char *filepath)
 {
        MovieClip *clip;
 
        errno = 0;
-       clip = BKE_movieclip_file_add(filepath);
+       clip = BKE_movieclip_file_add(bmain, filepath);
 
        if (!clip)
                BKE_reportf(reports, RPT_ERROR, "Cannot read '%s': %s", filepath,
@@ -596,28 +793,28 @@ static MovieClip *rna_Main_movieclip_load(Main *UNUSED(bmain), ReportList *repor
        return clip;
 }
 
-static void rna_Main_movieclips_remove(Main *UNUSED(bmain), PointerRNA *clip_ptr)
+static void rna_Main_movieclips_remove(Main *bmain, PointerRNA *clip_ptr)
 {
        MovieClip *clip = clip_ptr->data;
-       BKE_movieclip_unlink(G.main, clip);
-       BKE_libblock_free(&G.main->movieclip, clip);
+       BKE_movieclip_unlink(bmain, clip);
+       BKE_libblock_free(&bmain->movieclip, clip);
        RNA_POINTER_INVALIDATE(clip_ptr);
 }
 
-static Mask *rna_Main_mask_new(Main *UNUSED(bmain), const char *name)
+static Mask *rna_Main_mask_new(Main *bmain, const char *name)
 {
        Mask *mask;
 
-       mask = BKE_mask_new("Mask");
+       mask = BKE_mask_new(bmain, "Mask");
 
        return mask;
 }
 
-static void rna_Main_masks_remove(Main *UNUSED(bmain), PointerRNA *mask_ptr)
+static void rna_Main_masks_remove(Main *bmain, PointerRNA *mask_ptr)
 {
        Mask *mask = mask_ptr->data;
-       BKE_mask_free(G.main, mask);
-       BKE_libblock_free(&G.main->mask, mask);
+       BKE_mask_free(bmain, mask);
+       BKE_libblock_free(&bmain->mask, mask);
        RNA_POINTER_INVALIDATE(mask_ptr);
 }
 
@@ -911,6 +1108,12 @@ void RNA_def_main_meshes(BlenderRNA *brna, PropertyRNA *cprop)
        PropertyRNA *parm;
        PropertyRNA *prop;
 
+       static EnumPropertyItem mesh_type_items[] = {
+               {eModifierMode_Realtime, "PREVIEW", 0, "Preview", "Apply modifier preview settings"},
+               {eModifierMode_Render, "RENDER", 0, "Render", "Apply modifier render settings"},
+               {0, NULL, 0, NULL, NULL}
+       };
+
        RNA_def_property_srna(cprop, "BlendDataMeshes");
        srna = RNA_def_struct(brna, "BlendDataMeshes", NULL);
        RNA_def_struct_sdna(srna, "Main");
@@ -924,6 +1127,21 @@ void RNA_def_main_meshes(BlenderRNA *brna, PropertyRNA *cprop)
        parm = RNA_def_pointer(func, "mesh", "Mesh", "", "New mesh datablock");
        RNA_def_function_return(func, parm);
 
+       func = RNA_def_function(srna, "new_from_object", "rna_Main_meshes_new_from_object");
+       RNA_def_function_ui_description(func, "Add a new mesh created from object with modifiers applied");
+       RNA_def_function_flag(func, FUNC_USE_REPORTS);
+       parm = RNA_def_pointer(func, "scene", "Scene", "", "Scene within which to evaluate modifiers");
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       parm = RNA_def_pointer(func, "object", "Object", "", "Object to create mesh from");
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       parm = RNA_def_boolean(func, "apply_modifiers", 0, "", "Apply modifiers");
+       RNA_def_property_flag(parm, PROP_REQUIRED);
+       parm = RNA_def_enum(func, "settings", mesh_type_items, 0, "", "Modifier settings to apply");
+       RNA_def_property_flag(parm, PROP_REQUIRED);
+       parm = RNA_def_pointer(func, "mesh", "Mesh", "",
+                              "Mesh created from object, remove it if it is only used for export");
+       RNA_def_function_return(func, parm);
+
        func = RNA_def_function(srna, "remove", "rna_Main_meshes_remove");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a mesh from the current blendfile");
index 40b8d4cce6671f2f8daf7c86211ae0dc59ab4f5d..51725bda7f9b50f165b1652ab26874f71e0a9232 100644 (file)
@@ -65,8 +65,6 @@ static EnumPropertyItem space_items[] = {
 #include "BKE_context.h"
 #include "BKE_customdata.h"
 #include "BKE_depsgraph.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_displist.h"
 #include "BKE_font.h"
 #include "BKE_global.h"
 #include "BKE_main.h"
@@ -113,194 +111,7 @@ static void rna_Scene_mat_convert_space(Object *ob, ReportList *reports, bPoseCh
 /* settings: 0 - preview, 1 - render */
 static Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_modifiers, int settings)
 {
-       Mesh *tmpmesh;
-       Curve *tmpcu = NULL, *copycu;
-       Object *tmpobj = NULL;
-       int render = settings == eModifierMode_Render, i;
-       int cage = !apply_modifiers;
-
-       /* perform the mesh extraction based on type */
-       switch (ob->type) {
-               case OB_FONT:
-               case OB_CURVE:
-               case OB_SURF:
-               {
-                       ListBase dispbase = {NULL, NULL};
-                       DerivedMesh *derivedFinal = NULL;
-                       int uv_from_orco;
-
-                       /* copies object and modifiers (but not the data) */
-                       tmpobj = BKE_object_copy_with_caches(ob);
-                       tmpcu = (Curve *)tmpobj->data;
-                       tmpcu->id.us--;
-
-                       /* if getting the original caged mesh, delete object modifiers */
-                       if (cage)
-                               BKE_object_free_modifiers(tmpobj);
-
-                       /* copies the data */
-                       copycu = tmpobj->data = BKE_curve_copy((Curve *) ob->data);
-
-                       /* temporarily set edit so we get updates from edit mode, but
-                        * also because for text datablocks copying it while in edit
-                        * mode gives invalid data structures */
-                       copycu->editfont = tmpcu->editfont;
-                       copycu->editnurb = tmpcu->editnurb;
-
-                       /* get updated display list, and convert to a mesh */
-                       BKE_displist_make_curveTypes_forRender(sce, tmpobj, &dispbase, &derivedFinal, FALSE);
-
-                       copycu->editfont = NULL;
-                       copycu->editnurb = NULL;
-
-                       tmpobj->derivedFinal = derivedFinal;
-
-                       /* convert object type to mesh */
-                       uv_from_orco = (tmpcu->flag & CU_UV_ORCO) != 0;
-                       BKE_mesh_from_nurbs_displist(tmpobj, &dispbase, uv_from_orco);
-
-                       tmpmesh = tmpobj->data;
-
-                       BKE_displist_free(&dispbase);
-
-                       /* BKE_mesh_from_nurbs changes the type to a mesh, check it worked */
-                       if (tmpobj->type != OB_MESH) {
-                               BKE_libblock_free_us(&(G.main->object), tmpobj);
-                               BKE_report(reports, RPT_ERROR, "Cannot convert curve to mesh (does the curve have any segments?)");
-                               return NULL;
-                       }
-
-                       BKE_libblock_free_us(&G.main->object, tmpobj);
-                       break;
-               }
-
-               case OB_MBALL:
-               {
-                       /* metaballs don't have modifiers, so just convert to mesh */
-                       Object *basis_ob = BKE_mball_basis_find(sce, ob);
-                       /* todo, re-generatre for render-res */
-                       /* metaball_polygonize(scene, ob) */
-
-                       if (ob != basis_ob)
-                               return NULL;  /* only do basis metaball */
-                       
-                       tmpmesh = BKE_mesh_add("Mesh");
-                       /* BKE_mesh_add gives us a user count we don't need */
-                       tmpmesh->id.us--;
-
-                       if (render) {
-                               ListBase disp = {NULL, NULL};
-                               BKE_displist_make_mball_forRender(sce, ob, &disp);
-                               BKE_mesh_from_metaball(&disp, tmpmesh);
-                               BKE_displist_free(&disp);
-                       }
-                       else
-                               BKE_mesh_from_metaball(&ob->disp, tmpmesh);
-
-                       break;
-
-               }
-               case OB_MESH:
-                       /* copies object and modifiers (but not the data) */
-                       if (cage) {
-                               /* copies the data */
-                               tmpmesh = BKE_mesh_copy(ob->data);
-                               /* if not getting the original caged mesh, get final derived mesh */
-                       }
-                       else {
-                               /* Make a dummy mesh, saves copying */
-                               DerivedMesh *dm;
-                               /* CustomDataMask mask = CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL; */
-                               CustomDataMask mask = CD_MASK_MESH; /* this seems more suitable, exporter,
-                                                                * for example, needs CD_MASK_MDEFORMVERT */
-
-                               /* Write the display mesh into the dummy mesh */
-                               if (render)
-                                       dm = mesh_create_derived_render(sce, ob, mask);
-                               else
-                                       dm = mesh_create_derived_view(sce, ob, mask);
-               
-                               tmpmesh = BKE_mesh_add("Mesh");
-                               DM_to_mesh(dm, tmpmesh, ob);
-                               dm->release(dm);
-                       }
-
-                       /* BKE_mesh_add/copy gives us a user count we don't need */
-                       tmpmesh->id.us--;
-
-                       break;
-               default:
-                       BKE_report(reports, RPT_ERROR, "Object does not have geometry data");
-                       return NULL;
-       }
-
-       /* Copy materials to new mesh */
-       switch (ob->type) {
-               case OB_SURF:
-               case OB_FONT:
-               case OB_CURVE:
-                       tmpmesh->totcol = tmpcu->totcol;
-
-                       /* free old material list (if it exists) and adjust user counts */
-                       if (tmpcu->mat) {
-                               for (i = tmpcu->totcol; i-- > 0; ) {
-                                       /* are we an object material or data based? */
-
-                                       tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : tmpcu->mat[i];
-
-                                       if (tmpmesh->mat[i]) {
-                                               tmpmesh->mat[i]->id.us++;
-                                       }
-                               }
-                       }
-                       break;
-
-#if 0
-               /* Crashes when assigning the new material, not sure why */
-               case OB_MBALL:
-                       tmpmb = (MetaBall *)ob->data;
-                       tmpmesh->totcol = tmpmb->totcol;
-
-                       /* free old material list (if it exists) and adjust user counts */
-                       if (tmpmb->mat) {
-                               for (i = tmpmb->totcol; i-- > 0; ) {
-                                       tmpmesh->mat[i] = tmpmb->mat[i]; /* CRASH HERE ??? */
-                                       if (tmpmesh->mat[i]) {
-                                               tmpmb->mat[i]->id.us++;
-                                       }
-                               }
-                       }
-                       break;
-#endif
-
-               case OB_MESH:
-                       if (!cage) {
-                               Mesh *origmesh = ob->data;
-                               tmpmesh->flag = origmesh->flag;
-                               tmpmesh->mat = MEM_dupallocN(origmesh->mat);
-                               tmpmesh->totcol = origmesh->totcol;
-                               tmpmesh->smoothresh = origmesh->smoothresh;
-                               if (origmesh->mat) {
-                                       for (i = origmesh->totcol; i-- > 0; ) {
-                                               /* are we an object material or data based? */
-                                               tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : origmesh->mat[i];
-
-                                               if (tmpmesh->mat[i]) {
-                                                       tmpmesh->mat[i]->id.us++;
-                                               }
-                                       }
-                               }
-                       }
-                       break;
-       } /* end copy materials */
-
-       /* cycles and exporters rely on this still */
-       BKE_mesh_tessface_ensure(tmpmesh);
-
-       /* make sure materials get updated in objects */
-       test_object_materials(&tmpmesh->id);
-
-       return tmpmesh;
+       return rna_Main_meshes_new_from_object(G.main, reports, sce, ob, apply_modifiers, settings);
 }
 
 /* mostly a copy from convertblender.c */
index 0cf4f6a008fd9a91907442ead9f03954ca4d46eb..a3d93b5437e8f071ca078b551cff207a3933918f 100644 (file)
@@ -46,6 +46,7 @@
 
 #include "BKE_cdderivedmesh.h"
 #include "BKE_depsgraph.h"
+#include "BKE_global.h"
 #include "BKE_material.h"
 #include "BKE_mesh.h"
 #include "BKE_object.h"
@@ -295,7 +296,7 @@ static Object *AddNewBlenderMesh(Scene *scene, Base *base)
        basen->flag &= ~SELECT;
                                
        /* Initialize the mesh data associated with this object. */
-       ob_new->data = BKE_mesh_add("Mesh");
+       ob_new->data = BKE_mesh_add(G.main, "Mesh");
 
        /* Finally assign the object type. */
        ob_new->type = OB_MESH;