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 cdbd2fa..c61a7fa 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 f134416..0947b5a 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 4f54f93..12c9f6b 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 765a00b..fb9e9f4 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 91f0525..cfae159 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 2a27934..057cd79 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 536bbec..358f884 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 3e9803a..8c36a73 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 bfee5e8..f098def 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 244decf..205c7c7 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 fe88f0c..b195af1 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 b9bb67f..5aa82be 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 cc15cee..b40ad48 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 dd1b1a7..350eaf2 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 7a0eea1..662bfab 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 cfe562e..24535eb 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 25d2678..5777a40 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 718fa2f..5024b36 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 bfae1bd..54189e2 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 52c177f..e2f0fa5 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 be30eba..dc84bc6 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 78fdd26..f179637 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 7a23bff..6bb35e4 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 5ccf914..509442b 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 df2cc7c..74e44ea 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 3a705a0..b678ef6 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 70eaa00..9a32a50 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 d1842b9..34c2d14 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 a6e68b9..5f7662f 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 20d874e..639d256 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 82b0d23..39d76eb 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 59dd028..c536474 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 2f37db8..32cc5c6 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 05d7933..fd57a88 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 817068a..cd40f75 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 bda9240..960432d 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 f19dc93..4711765 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 b3f71e5..d939b9c 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 dba2fd5..20ccc33 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 69e368f..943d9e9 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 2062cc0..97bee32 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 aac1d9f..2312d80 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 dc8aed9..d34d5ea 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 f6599cc..f339180 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 a0f611a..3be9097 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 2e909f1..55a0f37 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 ad101c4..206f829 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 077a716..8a695ab 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 64832a1..c99f939 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 04815b9..b2c1b7f 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 e57e52d..e03a171 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 35f85f3..0a996c1 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 8457b27..3b2ddfe 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 7bf1a5d..9b683a1 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 fac835a..b2f5337 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 38ed903..fa258c9 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 53e1f49..e00db9b 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 618d545..408572c 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 a80d425..7e99e6c 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 cf4e76a..dfb69be 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 8bb51ed..2d2d29d 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 b47be15..2263156 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 321eaa3..fb4e4f6 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 4dd9c89..7572ca0 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 e82917f..e92d934 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 21966ef..1f209f9 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 76947d8..d908e84 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 e9ed3aa..ab94b88 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 40b8d4c..51725bd 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 0cf4f6a..a3d93b5 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;