diff options
Diffstat (limited to 'source/blender/editors/object/object_edit.c')
-rw-r--r-- | source/blender/editors/object/object_edit.c | 278 |
1 files changed, 118 insertions, 160 deletions
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index edd7b5dd1be..844ed168157 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -54,10 +54,11 @@ #include "DNA_property_types.h" #include "DNA_scene_types.h" #include "DNA_object_types.h" -#include "DNA_object_force.h" +#include "DNA_object_force_types.h" #include "DNA_meshdata_types.h" #include "DNA_vfont_types.h" #include "DNA_mesh_types.h" +#include "DNA_lattice_types.h" #include "IMB_imbuf_types.h" @@ -81,8 +82,10 @@ #include "BKE_sca.h" #include "BKE_softbody.h" #include "BKE_modifier.h" +#include "BKE_editlattice.h" #include "BKE_editmesh.h" #include "BKE_report.h" +#include "BKE_undo_system.h" #include "ED_armature.h" #include "ED_curve.h" @@ -91,7 +94,7 @@ #include "ED_lattice.h" #include "ED_object.h" #include "ED_screen.h" -#include "ED_util.h" +#include "ED_undo.h" #include "ED_image.h" #include "RNA_access.h" @@ -133,7 +136,7 @@ Object *ED_object_active_context(bContext *C) /* ********* clear/set restrict view *********/ -static int object_hide_view_clear_exec(bContext *C, wmOperator *UNUSED(op)) +static int object_hide_view_clear_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); ScrArea *sa = CTX_wm_area(C); @@ -141,12 +144,13 @@ static int object_hide_view_clear_exec(bContext *C, wmOperator *UNUSED(op)) Scene *scene = CTX_data_scene(C); Base *base; bool changed = false; + const bool select = RNA_boolean_get(op->ptr, "select"); /* XXX need a context loop to handle such cases */ for (base = FIRSTBASE; base; base = base->next) { if ((base->lay & v3d->lay) && base->object->restrictflag & OB_RESTRICT_VIEW) { if (!(base->object->restrictflag & OB_RESTRICT_SELECT)) { - base->flag |= SELECT; + SET_FLAG_FROM_TEST(base->flag, select, SELECT); } base->object->flag = base->flag; base->object->restrictflag &= ~OB_RESTRICT_VIEW; @@ -176,6 +180,8 @@ void OBJECT_OT_hide_view_clear(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "select", true, "Select", ""); } static int object_hide_view_set_exec(bContext *C, wmOperator *op) @@ -350,6 +356,9 @@ static bool ED_object_editmode_load_ex(Main *bmain, Object *obedit, const bool f if (obedit->type == OB_MESH) { Mesh *me = obedit->data; + if (me->edit_btmesh == NULL) { + return false; + } if (me->edit_btmesh->bm->totvert > MESH_MAX_VERTS) { error("Too many vertices"); @@ -363,15 +372,21 @@ static bool ED_object_editmode_load_ex(Main *bmain, Object *obedit, const bool f MEM_freeN(me->edit_btmesh); me->edit_btmesh = NULL; } - if (obedit->restore_mode & OB_MODE_WEIGHT_PAINT) { + /* will be recalculated as needed. */ + { ED_mesh_mirror_spatial_table(NULL, NULL, NULL, NULL, 'e'); ED_mesh_mirror_topo_table(NULL, NULL, 'e'); } } else if (obedit->type == OB_ARMATURE) { + const bArmature *arm = obedit->data; + if (arm->edbo == NULL) { + return false; + } ED_armature_from_edit(obedit->data); - if (freedata) + if (freedata) { ED_armature_edit_free(obedit->data); + } /* TODO(sergey): Pose channels might have been changed, so need * to inform dependency graph about this. But is it really the * best place to do this? @@ -379,27 +394,46 @@ static bool ED_object_editmode_load_ex(Main *bmain, Object *obedit, const bool f DAG_relations_tag_update(bmain); } else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { + const Curve *cu = obedit->data; + if (cu->editnurb == NULL) { + return false; + } ED_curve_editnurb_load(obedit); - if (freedata) ED_curve_editnurb_free(obedit); + if (freedata) { + ED_curve_editnurb_free(obedit); + } } else if (obedit->type == OB_FONT) { + const Curve *cu = obedit->data; + if (cu->editfont == NULL) { + return false; + } ED_curve_editfont_load(obedit); - if (freedata) ED_curve_editfont_free(obedit); + if (freedata) { + ED_curve_editfont_free(obedit); + } } else if (obedit->type == OB_LATTICE) { - ED_lattice_editlatt_load(obedit); - if (freedata) ED_lattice_editlatt_free(obedit); + const Lattice *lt = obedit->data; + if (lt->editlatt == NULL) { + return false; + } + BKE_editlattice_load(obedit); + if (freedata) { + BKE_editlattice_free(obedit); + } } else if (obedit->type == OB_MBALL) { + const MetaBall *mb = obedit->data; + if (mb->editelems == NULL) { + return false; + } ED_mball_editmball_load(obedit); - if (freedata) ED_mball_editmball_free(obedit); + if (freedata) { + ED_mball_editmball_free(obedit); + } } - /* Tag update so no access to freed data referenced from - * derived cache will happen. - */ - DAG_id_tag_update((ID *)obedit->data, 0); - return true; } @@ -409,17 +443,20 @@ bool ED_object_editmode_load(Object *obedit) return ED_object_editmode_load_ex(G.main, obedit, false); } -void ED_object_editmode_exit(bContext *C, int flag) +/** + * \param C: Can be NULL, only if #EM_DO_UNDO isn't set. + * \param flag: + * - Only in exceptional cases should #EM_DO_UNDO NOT be in the flag. + * - If #EM_FREEDATA isn't in the flag, use ED_object_editmode_load directly. + */ +void ED_object_editmode_exit_ex(bContext *C, Scene *scene, Object *obedit, int flag) { - /* Note! only in exceptional cases should 'EM_DO_UNDO' NOT be in the flag */ - /* Note! if 'EM_FREEDATA' isn't in the flag, use ED_object_editmode_load directly */ - Scene *scene = CTX_data_scene(C); - Object *obedit = CTX_data_edit_object(C); + BLI_assert(C || !(flag & EM_DO_UNDO)); const bool freedata = (flag & EM_FREEDATA) != 0; if (flag & EM_WAITCURSOR) waitcursor(1); - if (ED_object_editmode_load_ex(CTX_data_main(C), obedit, freedata) == false) { + if (ED_object_editmode_load_ex(G.main, obedit, freedata) == false) { /* in rare cases (background mode) its possible active object * is flagged for editmode, without 'obedit' being set [#35489] */ if (UNLIKELY(scene->basact && (scene->basact->object->mode & OB_MODE_EDIT))) { @@ -453,7 +490,12 @@ void ED_object_editmode_exit(bContext *C, int flag) if (flag & EM_DO_UNDO) ED_undo_push(C, "Editmode"); - WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, scene); + if (C != NULL) { + WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, scene); + } + else { + WM_main_add_notifier(NC_SCENE | ND_MODE | NS_MODE_OBJECT, scene); + } obedit->mode &= ~OB_MODE_EDIT; } @@ -461,6 +503,12 @@ void ED_object_editmode_exit(bContext *C, int flag) if (flag & EM_WAITCURSOR) waitcursor(0); } +void ED_object_editmode_exit(bContext *C, int flag) +{ + Scene *scene = CTX_data_scene(C); + Object *obedit = CTX_data_edit_object(C); + ED_object_editmode_exit_ex(C, scene, obedit, flag); +} void ED_object_editmode_enter(bContext *C, int flag) { @@ -471,7 +519,7 @@ void ED_object_editmode_enter(bContext *C, int flag) View3D *v3d = NULL; bool ok = false; - if (ID_IS_LINKED_DATABLOCK(scene)) return; + if (ID_IS_LINKED(scene)) return; if (sa && sa->spacetype == SPACE_VIEW3D) v3d = sa->spacedata.first; @@ -507,7 +555,7 @@ void ED_object_editmode_enter(bContext *C, int flag) /* note, when switching scenes the object can have editmode data but * not be scene->obedit: bug 22954, this avoids calling self eternally */ if ((ob->restore_mode & OB_MODE_EDIT) == 0) - ED_object_toggle_modes(C, ob->mode); + ED_object_mode_toggle(C, ob->mode); ob->mode = OB_MODE_EDIT; @@ -518,7 +566,7 @@ void ED_object_editmode_enter(bContext *C, int flag) const bool use_key_index = mesh_needs_keyindex(ob->data); - EDBM_mesh_make(scene->toolsettings, ob, use_key_index); + EDBM_mesh_make(ob, scene->toolsettings->selectmode, use_key_index); em = BKE_editmesh_from_object(ob); if (LIKELY(em)) { @@ -540,7 +588,7 @@ void ED_object_editmode_enter(bContext *C, int flag) * BKE_object_obdata_is_libdata that prevent the bugfix #6614, so * i add this little hack here. */ - if (ID_IS_LINKED_DATABLOCK(arm)) { + if (ID_IS_LINKED(arm)) { error_libdata(); return; } @@ -569,7 +617,7 @@ void ED_object_editmode_enter(bContext *C, int flag) else if (ob->type == OB_LATTICE) { scene->obedit = ob; /* XXX for context */ ok = 1; - ED_lattice_editlatt_make(ob); + BKE_editlattice_make(ob); WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_EDITMODE_LATTICE, scene); } @@ -610,7 +658,7 @@ static int editmode_toggle_exec(bContext *C, wmOperator *op) if (!is_mode_set) ED_object_editmode_enter(C, EM_WAITCURSOR); else - ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR); /* had EM_DO_UNDO but op flag calls undo too [#24685] */ + ED_object_editmode_exit(C, EM_FREEDATA | EM_WAITCURSOR); /* had EM_DO_UNDO but op flag calls undo too [#24685] */ ED_space_image_uv_sculpt_update(CTX_wm_manager(C), scene); @@ -622,7 +670,7 @@ static int editmode_toggle_poll(bContext *C) Object *ob = CTX_data_active_object(C); /* covers proxies too */ - if (ELEM(NULL, ob, ob->data) || ID_IS_LINKED_DATABLOCK(ob->data)) + if (ELEM(NULL, ob, ob->data) || ID_IS_LINKED(ob->data)) return 0; /* if hidden but in edit mode, we still display */ @@ -655,7 +703,7 @@ static int posemode_exec(bContext *C, wmOperator *op) Base *base = CTX_data_active_base(C); Object *ob = base->object; const int mode_flag = OB_MODE_POSE; - const bool is_mode_set = (ob->mode & mode_flag) != 0; + bool is_mode_set = (ob->mode & mode_flag) != 0; if (!is_mode_set) { if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) { @@ -666,12 +714,15 @@ static int posemode_exec(bContext *C, wmOperator *op) if (ob->type == OB_ARMATURE) { if (ob == CTX_data_edit_object(C)) { ED_object_editmode_exit(C, EM_FREEDATA | EM_DO_UNDO); - ED_armature_enter_posemode(C, base); + is_mode_set = false; + } + + if (is_mode_set) { + ED_object_posemode_exit(C, ob); + } + else { + ED_object_posemode_enter(C, ob); } - else if (is_mode_set) - ED_armature_exit_posemode(C, base); - else - ED_armature_enter_posemode(C, base); return OPERATOR_FINISHED; } @@ -773,9 +824,9 @@ static void copymenu_logicbricks(Scene *scene, View3D *v3d, Object *ob) /* now copy it, this also works without logicbricks! */ clear_sca_new_poins_ob(ob); - copy_sensors(&base->object->sensors, &ob->sensors); - copy_controllers(&base->object->controllers, &ob->controllers); - copy_actuators(&base->object->actuators, &ob->actuators); + copy_sensors(&base->object->sensors, &ob->sensors, 0); + copy_controllers(&base->object->controllers, &ob->controllers, 0); + copy_actuators(&base->object->actuators, &ob->actuators, 0); set_sca_new_poins_ob(base->object); /* some menu settings */ @@ -849,7 +900,7 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event) Nurb *nu; bool do_depgraph_update = false; - if (ID_IS_LINKED_DATABLOCK(scene)) return; + if (ID_IS_LINKED(scene)) return; if (!(ob = OBACT)) return; @@ -934,7 +985,7 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event) base->object->collision_boundtype = ob->collision_boundtype; } base->object->margin = ob->margin; - base->object->bsoft = copy_bulletsoftbody(ob->bsoft); + base->object->bsoft = copy_bulletsoftbody(ob->bsoft, 0); } else if (event == 17) { /* tex space */ @@ -1042,7 +1093,7 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event) base->object->softflag = ob->softflag; if (base->object->soft) sbFree(base->object->soft); - base->object->soft = copy_softbody(ob->soft, false); + base->object->soft = copy_softbody(ob->soft, 0); if (!modifiers_findByType(base->object, eModifierType_Softbody)) { BLI_addhead(&base->object->modifiers, modifier_new(eModifierType_Softbody)); @@ -1050,7 +1101,7 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event) } else if (event == 26) { #if 0 // XXX old animation system - copy_nlastrips(&base->object->nlastrips, &ob->nlastrips); + BKE_nlastrip_copy(s(&base->object->nlastrips, &ob->nlastrips); #endif // XXX old animation system } else if (event == 27) { /* autosmooth */ @@ -1158,13 +1209,16 @@ void ED_object_check_force_modifiers(Main *bmain, Scene *scene, Object *object) /* add/remove modifier as needed */ if (!md) { - if (pd && (pd->shape == PFIELD_SHAPE_SURFACE) && ELEM(pd->forcefield, PFIELD_GUIDE, PFIELD_TEXTURE) == 0) - if (ELEM(object->type, OB_MESH, OB_SURF, OB_FONT, OB_CURVE)) + if (pd && (pd->shape == PFIELD_SHAPE_SURFACE) && !ELEM(pd->forcefield, 0, PFIELD_GUIDE, PFIELD_TEXTURE)) { + if (ELEM(object->type, OB_MESH, OB_SURF, OB_FONT, OB_CURVE)) { ED_object_modifier_add(NULL, bmain, scene, object, NULL, eModifierType_Surface); + } + } } else { - if (!pd || pd->shape != PFIELD_SHAPE_SURFACE || pd->forcefield != PFIELD_FORCE) + if (!pd || (pd->shape != PFIELD_SHAPE_SURFACE) || ELEM(pd->forcefield, 0, PFIELD_GUIDE, PFIELD_TEXTURE)) { ED_object_modifier_remove(NULL, bmain, object, md); + } } } @@ -1437,7 +1491,7 @@ static int shade_smooth_exec(bContext *C, wmOperator *op) { data = ob->data; - if (data && ID_IS_LINKED_DATABLOCK(data)) { + if (data && ID_IS_LINKED(data)) { linked_data = true; continue; } @@ -1520,7 +1574,7 @@ static void UNUSED_FUNCTION(image_aspect) (Scene *scene, View3D *v3d) int a, b, done; if (scene->obedit) return; // XXX get from context - if (ID_IS_LINKED_DATABLOCK(scene)) return; + if (ID_IS_LINKED(scene)) return; for (base = FIRSTBASE; base; base = base->next) { if (TESTBASELIB(v3d, base)) { @@ -1571,9 +1625,10 @@ static void UNUSED_FUNCTION(image_aspect) (Scene *scene, View3D *v3d) } -static EnumPropertyItem *object_mode_set_itemsf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) +static const EnumPropertyItem *object_mode_set_itemsf( + bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) { - EnumPropertyItem *input = rna_enum_object_mode_items; + const EnumPropertyItem *input = rna_enum_object_mode_items; EnumPropertyItem *item = NULL; Object *ob; bGPdata *gpd; @@ -1620,91 +1675,6 @@ static EnumPropertyItem *object_mode_set_itemsf(bContext *C, PointerRNA *UNUSED( return item; } -static const char *object_mode_op_string(int mode) -{ - if (mode & OB_MODE_EDIT) - return "OBJECT_OT_editmode_toggle"; - if (mode == OB_MODE_SCULPT) - return "SCULPT_OT_sculptmode_toggle"; - if (mode == OB_MODE_VERTEX_PAINT) - return "PAINT_OT_vertex_paint_toggle"; - if (mode == OB_MODE_WEIGHT_PAINT) - return "PAINT_OT_weight_paint_toggle"; - if (mode == OB_MODE_TEXTURE_PAINT) - return "PAINT_OT_texture_paint_toggle"; - if (mode == OB_MODE_PARTICLE_EDIT) - return "PARTICLE_OT_particle_edit_toggle"; - if (mode == OB_MODE_POSE) - return "OBJECT_OT_posemode_toggle"; - if (mode == OB_MODE_GPENCIL) - return "GPENCIL_OT_editmode_toggle"; - return NULL; -} - -/* checks the mode to be set is compatible with the object - * should be made into a generic function - */ -static bool object_mode_compat_test(Object *ob, ObjectMode mode) -{ - if (ob) { - if (mode == OB_MODE_OBJECT) - return true; - else if (mode == OB_MODE_GPENCIL) - return true; /* XXX: assume this is the case for now... */ - - switch (ob->type) { - case OB_MESH: - if (mode & (OB_MODE_EDIT | OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | - OB_MODE_TEXTURE_PAINT | OB_MODE_PARTICLE_EDIT)) - { - return true; - } - break; - case OB_CURVE: - case OB_SURF: - case OB_FONT: - case OB_MBALL: - if (mode & (OB_MODE_EDIT)) - return true; - break; - case OB_LATTICE: - if (mode & (OB_MODE_EDIT | OB_MODE_WEIGHT_PAINT)) - return true; - break; - case OB_ARMATURE: - if (mode & (OB_MODE_EDIT | OB_MODE_POSE)) - return true; - break; - } - } - - return false; -} - -/** - * Sets the mode to a compatible state (use before entering the mode). - * - * This is so each mode's exec function can call - */ -bool ED_object_mode_compat_set(bContext *C, Object *ob, int mode, ReportList *reports) -{ - bool ok; - if (!ELEM(ob->mode, mode, OB_MODE_OBJECT)) { - const char *opstring = object_mode_op_string(ob->mode); - WM_operator_name_call(C, opstring, WM_OP_EXEC_REGION_WIN, NULL); - ok = ELEM(ob->mode, mode, OB_MODE_OBJECT); - if (!ok) { - wmOperatorType *ot = WM_operatortype_find(opstring, false); - BKE_reportf(reports, RPT_ERROR, "Unable to execute '%s', error changing modes", ot->name); - } - } - else { - ok = true; - } - - return ok; -} - static int object_mode_set_poll(bContext *C) { /* Since Grease Pencil editmode is also handled here, @@ -1722,8 +1692,8 @@ static int object_mode_set_exec(bContext *C, wmOperator *op) { Object *ob = CTX_data_active_object(C); bGPdata *gpd = CTX_data_gpencil_data(C); - ObjectMode mode = RNA_enum_get(op->ptr, "mode"); - ObjectMode restore_mode = (ob) ? ob->mode : OB_MODE_OBJECT; + eObjectMode mode = RNA_enum_get(op->ptr, "mode"); + eObjectMode restore_mode = (ob) ? ob->mode : OB_MODE_OBJECT; const bool toggle = RNA_boolean_get(op->ptr, "toggle"); if (gpd) { @@ -1744,7 +1714,7 @@ static int object_mode_set_exec(bContext *C, wmOperator *op) } } - if (!ob || !object_mode_compat_test(ob, mode)) + if (!ob || !ED_object_mode_compat_test(ob, mode)) return OPERATOR_PASS_THROUGH; if (ob->mode != mode) { @@ -1755,20 +1725,20 @@ static int object_mode_set_exec(bContext *C, wmOperator *op) /* Exit current mode if it's not the mode we're setting */ if (mode != OB_MODE_OBJECT && (ob->mode != mode || toggle)) { /* Enter new mode */ - ED_object_toggle_modes(C, mode); + ED_object_mode_toggle(C, mode); } if (toggle) { /* Special case for Object mode! */ if (mode == OB_MODE_OBJECT && restore_mode == OB_MODE_OBJECT && ob->restore_mode != OB_MODE_OBJECT) { - ED_object_toggle_modes(C, ob->restore_mode); + ED_object_mode_toggle(C, ob->restore_mode); } else if (ob->mode == mode) { /* For toggling, store old mode so we know what to go back to */ ob->restore_mode = restore_mode; } else if (ob->restore_mode != OB_MODE_OBJECT && ob->restore_mode != mode) { - ED_object_toggle_modes(C, ob->restore_mode); + ED_object_mode_toggle(C, ob->restore_mode); } } @@ -1800,18 +1770,6 @@ void OBJECT_OT_mode_set(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } - - -void ED_object_toggle_modes(bContext *C, int mode) -{ - if (mode != OB_MODE_OBJECT) { - const char *opstring = object_mode_op_string(mode); - if (opstring) { - WM_operator_name_call(C, opstring, WM_OP_EXEC_REGION_WIN, NULL); - } - } -} - /************************ Game Properties ***********************/ static int game_property_new_exec(bContext *C, wmOperator *op) @@ -1936,7 +1894,7 @@ static int game_property_move(bContext *C, wmOperator *op) void OBJECT_OT_game_property_move(wmOperatorType *ot) { - static EnumPropertyItem direction_property_move[] = { + static const EnumPropertyItem direction_property_move[] = { {GAME_PROPERTY_MOVE_UP, "UP", 0, "Up", ""}, {GAME_PROPERTY_MOVE_DOWN, "DOWN", 0, "Down", ""}, {0, NULL, 0, NULL, NULL} @@ -1969,14 +1927,14 @@ void OBJECT_OT_game_property_move(wmOperatorType *ot) #define COPY_PROPERTIES_MERGE 2 #define COPY_PROPERTIES_COPY 3 -static EnumPropertyItem game_properties_copy_operations[] = { +static const EnumPropertyItem game_properties_copy_operations[] = { {COPY_PROPERTIES_REPLACE, "REPLACE", 0, "Replace Properties", ""}, {COPY_PROPERTIES_MERGE, "MERGE", 0, "Merge Properties", ""}, {COPY_PROPERTIES_COPY, "COPY", 0, "Copy a Property", ""}, {0, NULL, 0, NULL, NULL} }; -static EnumPropertyItem *gameprops_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) +static const EnumPropertyItem *gameprops_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) { Object *ob = ED_object_active_context(C); EnumPropertyItem tmp = {0, "", 0, "", ""}; @@ -2106,9 +2064,9 @@ static int logicbricks_copy_exec(bContext *C, wmOperator *UNUSED(op)) /* now copy it, this also works without logicbricks! */ clear_sca_new_poins_ob(ob); - copy_sensors(&ob_iter->sensors, &ob->sensors); - copy_controllers(&ob_iter->controllers, &ob->controllers); - copy_actuators(&ob_iter->actuators, &ob->actuators); + copy_sensors(&ob_iter->sensors, &ob->sensors, 0); + copy_controllers(&ob_iter->controllers, &ob->controllers, 0); + copy_actuators(&ob_iter->actuators, &ob->actuators, 0); set_sca_new_poins_ob(ob_iter); /* some menu settings */ @@ -2169,7 +2127,7 @@ static int game_physics_copy_exec(bContext *C, wmOperator *UNUSED(op)) copy_v3_v3(ob_iter->anisotropicFriction, ob->anisotropicFriction); ob_iter->collision_boundtype = ob->collision_boundtype; ob_iter->margin = ob->margin; - ob_iter->bsoft = copy_bulletsoftbody(ob->bsoft); + ob_iter->bsoft = copy_bulletsoftbody(ob->bsoft, 0); if (ob->restrictflag & OB_RESTRICT_RENDER) ob_iter->restrictflag |= OB_RESTRICT_RENDER; else |