Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/object/object_edit.c')
-rw-r--r--source/blender/editors/object/object_edit.c851
1 files changed, 534 insertions, 317 deletions
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 18ed6dc1e10..a938018d97b 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -96,6 +96,7 @@
#include "BKE_material.h"
#include "BKE_mball.h"
#include "BKE_mesh.h"
+#include "BKE_tessmesh.h"
#include "BKE_nla.h"
#include "BKE_object.h"
#include "BKE_particle.h"
@@ -108,7 +109,6 @@
#include "BKE_texture.h"
#include "BKE_utildefines.h"
#include "BKE_modifier.h"
-#include "BKE_tessmesh.h"
#include "ED_anim_api.h"
#include "ED_armature.h"
@@ -117,12 +117,11 @@
#include "ED_mesh.h"
#include "ED_object.h"
#include "ED_screen.h"
+#include "ED_transform.h"
#include "ED_types.h"
#include "ED_util.h"
#include "ED_view3d.h"
-#include "BIF_transform.h"
-
#include "UI_interface.h"
#include "RNA_access.h"
@@ -245,17 +244,19 @@ void ED_object_base_init_from_view(bContext *C, Base *base)
/* ******************* add object operator ****************** */
static EnumPropertyItem prop_object_types[] = {
- {OB_EMPTY, "EMPTY", "Empty", ""},
- {OB_MESH, "MESH", "Mesh", ""},
- {OB_CURVE, "CURVE", "Curve", ""},
- {OB_SURF, "SURFACE", "Surface", ""},
- {OB_FONT, "TEXT", "Text", ""},
- {OB_MBALL, "META", "Meta", ""},
- {OB_LAMP, "LAMP", "Lamp", ""},
- {OB_CAMERA, "CAMERA", "Camera", ""},
- {OB_ARMATURE, "ARMATURE", "Armature", ""},
- {OB_LATTICE, "LATTICE", "Lattice", ""},
- {0, NULL, NULL, NULL}
+ {OB_MESH, "MESH", 0, "Mesh", ""},
+ {OB_CURVE, "CURVE", 0, "Curve", ""},
+ {OB_SURF, "SURFACE", 0, "Surface", ""},
+ {OB_MBALL, "META", 0, "Meta", ""},
+ {OB_FONT, "TEXT", 0, "Text", ""},
+ {0, "", 0, NULL, NULL},
+ {OB_ARMATURE, "ARMATURE", 0, "Armature", ""},
+ {OB_LATTICE, "LATTICE", 0, "Lattice", ""},
+ {OB_EMPTY, "EMPTY", 0, "Empty", ""},
+ {0, "", 0, NULL, NULL},
+ {OB_CAMERA, "CAMERA", 0, "Camera", ""},
+ {OB_LAMP, "LAMP", 0, "Lamp", ""},
+ {0, NULL, 0, NULL, NULL}
};
@@ -322,16 +323,17 @@ void OBJECT_OT_object_add(wmOperatorType *ot)
/* ****** work both in and outside editmode ****** */
static EnumPropertyItem prop_mesh_types[] = {
- {0, "PLANE", "Plane", ""},
- {1, "CUBE", "Cube", ""},
- {2, "CIRCLE", "Circle", ""},
- {3, "UVSPHERE", "UVsphere", ""},
- {4, "ICOSPHERE", "Icosphere", ""},
- {5, "CYLINDER", "Cylinder", ""},
- {6, "CONE", "Cone", ""},
- {7, "GRID", "Grid", ""},
- {8, "MONKEY", "Monkey", ""},
- {0, NULL, NULL, NULL}
+ {0, "PLANE", ICON_MESH_PLANE, "Plane", ""},
+ {1, "CUBE", ICON_MESH_CUBE, "Cube", ""},
+ {2, "CIRCLE", ICON_MESH_CIRCLE, "Circle", ""},
+ {3, "UVSPHERE", ICON_MESH_UVSPHERE, "UVsphere", ""},
+ {4, "ICOSPHERE", ICON_MESH_ICOSPHERE, "Icosphere", ""},
+ {5, "CYLINDER", ICON_MESH_TUBE, "Cylinder", ""},
+ {6, "CONE", ICON_MESH_CONE, "Cone", ""},
+ {0, "", 0, NULL, NULL},
+ {7, "GRID", ICON_MESH_GRID, "Grid", ""},
+ {8, "MONKEY", ICON_MESH_MONKEY, "Monkey", ""},
+ {0, NULL, 0, NULL, NULL}
};
static int object_add_mesh_exec(bContext *C, wmOperator *op)
@@ -341,7 +343,7 @@ static int object_add_mesh_exec(bContext *C, wmOperator *op)
if(obedit==NULL || obedit->type!=OB_MESH) {
object_add_type(C, OB_MESH);
- ED_object_enter_editmode(C, 0);
+ ED_object_enter_editmode(C, EM_DO_UNDO);
newob = 1;
}
else DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA);
@@ -389,7 +391,7 @@ static int object_add_mesh_exec(bContext *C, wmOperator *op)
void OBJECT_OT_mesh_add(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Mesh";
+ ot->name= "Add Mesh";
ot->description = "Add a mesh object to the scene.";
ot->idname= "OBJECT_OT_mesh_add";
@@ -399,19 +401,19 @@ void OBJECT_OT_mesh_add(wmOperatorType *ot)
ot->poll= ED_operator_scene_editable;
- /* flags */
- ot->flag= 0;
+ /* flags: no register or undo, this operator calls operators */
+ ot->flag= 0; //OPTYPE_REGISTER|OPTYPE_UNDO;
RNA_def_enum(ot->srna, "type", prop_mesh_types, 0, "Primitive", "");
}
static EnumPropertyItem prop_curve_types[] = {
- {CU_BEZIER|CU_2D|CU_PRIM_CURVE, "BEZIER_CURVE", "Bezier Curve", ""},
- {CU_BEZIER|CU_2D|CU_PRIM_CIRCLE, "BEZIER_CIRCLE", "Bezier Circle", ""},
- {CU_NURBS|CU_2D|CU_PRIM_CURVE, "NURBS_CURVE", "NURBS Curve", ""},
- {CU_NURBS|CU_2D|CU_PRIM_CIRCLE, "NURBS_CIRCLE", "NURBS Circle", ""},
- {CU_NURBS|CU_2D|CU_PRIM_PATH, "PATH", "Path", ""},
- {0, NULL, NULL, NULL}
+ {CU_BEZIER|CU_2D|CU_PRIM_CURVE, "BEZIER_CURVE", ICON_CURVE_BEZCURVE, "Bezier Curve", ""},
+ {CU_BEZIER|CU_2D|CU_PRIM_CIRCLE, "BEZIER_CIRCLE", ICON_CURVE_BEZCIRCLE, "Bezier Circle", ""},
+ {CU_NURBS|CU_2D|CU_PRIM_CURVE, "NURBS_CURVE", ICON_CURVE_NCURVE, "NURBS Curve", ""},
+ {CU_NURBS|CU_2D|CU_PRIM_CIRCLE, "NURBS_CIRCLE", ICON_CURVE_NCIRCLE, "NURBS Circle", ""},
+ {CU_NURBS|CU_2D|CU_PRIM_PATH, "PATH", ICON_CURVE_PATH, "Path", ""},
+ {0, NULL, 0, NULL, NULL}
};
static int object_add_curve_exec(bContext *C, wmOperator *op)
@@ -463,7 +465,7 @@ static int object_add_curve_invoke(bContext *C, wmOperator *op, wmEvent *event)
void OBJECT_OT_curve_add(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Curve";
+ ot->name= "Add Curve";
ot->description = "Add a curve object to the scene.";
ot->idname= "OBJECT_OT_curve_add";
@@ -480,13 +482,13 @@ void OBJECT_OT_curve_add(wmOperatorType *ot)
}
static EnumPropertyItem prop_surface_types[]= {
- {CU_PRIM_CURVE|CU_NURBS, "NURBS_CURVE", "NURBS Curve", ""},
- {CU_PRIM_CIRCLE|CU_NURBS, "NURBS_CIRCLE", "NURBS Circle", ""},
- {CU_PRIM_PATCH|CU_NURBS, "NURBS_SURFACE", "NURBS Surface", ""},
- {CU_PRIM_TUBE|CU_NURBS, "NURBS_TUBE", "NURBS Tube", ""},
- {CU_PRIM_SPHERE|CU_NURBS, "NURBS_SPHERE", "NURBS Sphere", ""},
- {CU_PRIM_DONUT|CU_NURBS, "NURBS_DONUT", "NURBS Donut", ""},
- {0, NULL, NULL, NULL}
+ {CU_PRIM_CURVE|CU_NURBS, "NURBS_CURVE", ICON_SURFACE_NCURVE, "NURBS Curve", ""},
+ {CU_PRIM_CIRCLE|CU_NURBS, "NURBS_CIRCLE", ICON_SURFACE_NCIRCLE, "NURBS Circle", ""},
+ {CU_PRIM_PATCH|CU_NURBS, "NURBS_SURFACE", ICON_SURFACE_NSURFACE, "NURBS Surface", ""},
+ {CU_PRIM_TUBE|CU_NURBS, "NURBS_TUBE", ICON_SURFACE_NTUBE, "NURBS Tube", ""},
+ {CU_PRIM_SPHERE|CU_NURBS, "NURBS_SPHERE", ICON_SURFACE_NSPHERE, "NURBS Sphere", ""},
+ {CU_PRIM_DONUT|CU_NURBS, "NURBS_DONUT", ICON_SURFACE_NDONUT, "NURBS Donut", ""},
+ {0, NULL, 0, NULL, NULL}
};
static int object_add_surface_exec(bContext *C, wmOperator *op)
@@ -521,7 +523,7 @@ static int object_add_surface_exec(bContext *C, wmOperator *op)
void OBJECT_OT_surface_add(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Surface";
+ ot->name= "Add Surface";
ot->description = "Add a surface object to the scene.";
ot->idname= "OBJECT_OT_surface_add";
@@ -558,7 +560,7 @@ static int object_add_text_exec(bContext *C, wmOperator *op)
void OBJECT_OT_text_add(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Text";
+ ot->name= "Add Text";
ot->description = "Add a text object to the scene";
ot->idname= "OBJECT_OT_text_add";
@@ -603,7 +605,7 @@ static int object_armature_add_exec(bContext *C, wmOperator *op)
void OBJECT_OT_armature_add(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Armature";
+ ot->name= "Add Armature";
ot->description = "Add an armature object to the scene.";
ot->idname= "OBJECT_OT_armature_add";
@@ -621,16 +623,18 @@ static int object_primitive_add_invoke(bContext *C, wmOperator *op, wmEvent *eve
uiPopupMenu *pup= uiPupMenuBegin(C, "Add Object", 0);
uiLayout *layout= uiPupMenuLayout(pup);
- uiItemMenuEnumO(layout, NULL, ICON_OUTLINER_OB_MESH, "OBJECT_OT_mesh_add", "type");
- uiItemMenuEnumO(layout, NULL, ICON_OUTLINER_OB_CURVE, "OBJECT_OT_curve_add", "type");
- uiItemMenuEnumO(layout, NULL, ICON_OUTLINER_OB_SURFACE, "OBJECT_OT_surface_add", "type");
- uiItemO(layout, NULL, ICON_OUTLINER_OB_FONT, "OBJECT_OT_text_add");
+ uiItemMenuEnumO(layout, "Mesh", ICON_OUTLINER_OB_MESH, "OBJECT_OT_mesh_add", "type");
+ uiItemMenuEnumO(layout, "Curve", ICON_OUTLINER_OB_CURVE, "OBJECT_OT_curve_add", "type");
+ uiItemMenuEnumO(layout, "Surface", ICON_OUTLINER_OB_SURFACE, "OBJECT_OT_surface_add", "type");
uiItemEnumO(layout, NULL, ICON_OUTLINER_OB_META, "OBJECT_OT_object_add", "type", OB_MBALL);
+ uiItemO(layout, "Text", ICON_OUTLINER_OB_FONT, "OBJECT_OT_text_add");
+ uiItemS(layout);
+ uiItemO(layout, "Armature", ICON_OUTLINER_OB_ARMATURE, "OBJECT_OT_armature_add");
+ uiItemEnumO(layout, NULL, ICON_OUTLINER_OB_LATTICE, "OBJECT_OT_object_add", "type", OB_LATTICE);
+ uiItemEnumO(layout, NULL, ICON_OUTLINER_OB_EMPTY, "OBJECT_OT_object_add", "type", OB_EMPTY);
+ uiItemS(layout);
uiItemEnumO(layout, NULL, ICON_OUTLINER_OB_CAMERA, "OBJECT_OT_object_add", "type", OB_CAMERA);
uiItemEnumO(layout, NULL, ICON_OUTLINER_OB_LAMP, "OBJECT_OT_object_add", "type", OB_LAMP);
- uiItemEnumO(layout, NULL, ICON_OUTLINER_OB_EMPTY, "OBJECT_OT_object_add", "type", OB_EMPTY);
- uiItemO(layout, NULL, ICON_OUTLINER_OB_ARMATURE, "OBJECT_OT_armature_add");
- uiItemEnumO(layout, NULL, ICON_OUTLINER_OB_LATTICE, "OBJECT_OT_object_add", "type", OB_LATTICE);
uiPupMenuEnd(C, pup);
@@ -701,8 +705,8 @@ void OBJECT_OT_delete(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Delete Objects";
- ot->description = "Delete the object.";
+ ot->name= "Delete";
+ ot->description = "Delete selected objects.";
ot->idname= "OBJECT_OT_delete";
/* api callbacks */
@@ -842,13 +846,14 @@ static void copy_object_set_idnew(Scene *scene, View3D *v3d, int dupflag)
}
-static int return_editmesh_indexar(EditMesh *em, int *tot, int **indexar, float *cent)
+static int return_editmesh_indexar(BMEditMesh *em, int *tot, int **indexar, float *cent)
{
- EditVert *eve;
+ BMVert *eve;
+ BMIter iter;
int *index, nr, totvert=0;
- for(eve= em->verts.first; eve; eve= eve->next) {
- if(eve->f & SELECT) totvert++;
+ BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
+ if(BM_TestHFlag(eve, BM_SELECT)) totvert++;
}
if(totvert==0) return 0;
@@ -857,8 +862,8 @@ static int return_editmesh_indexar(EditMesh *em, int *tot, int **indexar, float
nr= 0;
cent[0]= cent[1]= cent[2]= 0.0;
- for(eve= em->verts.first; eve; eve= eve->next) {
- if(eve->f & SELECT) {
+ BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
+ if(BM_TestHFlag(eve, BM_SELECT)) {
*index= nr; index++;
VecAddf(cent, cent, eve->co);
}
@@ -870,19 +875,19 @@ static int return_editmesh_indexar(EditMesh *em, int *tot, int **indexar, float
return totvert;
}
-static int return_editmesh_vgroup(Object *obedit, EditMesh *em, char *name, float *cent)
+static int return_editmesh_vgroup(Object *obedit, BMEditMesh *em, char *name, float *cent)
{
MDeformVert *dvert;
- EditVert *eve;
+ BMVert *eve;
+ BMIter iter;
int i, totvert=0;
cent[0]= cent[1]= cent[2]= 0.0;
if(obedit->actdef) {
-
/* find the vertices */
- for(eve= em->verts.first; eve; eve= eve->next) {
- dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
+ BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
+ dvert= CustomData_em_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT);
if(dvert) {
for(i=0; i<dvert->totweight; i++){
@@ -907,19 +912,18 @@ static int return_editmesh_vgroup(Object *obedit, EditMesh *em, char *name, floa
static void select_editmesh_hook(Object *ob, HookModifierData *hmd)
{
Mesh *me= ob->data;
- EditMesh *em= BKE_mesh_get_editmesh(me);
- EditVert *eve;
+ BMEditMesh *em= me->edit_btmesh;
+ BMVert *eve;
+ BMIter iter;
int index=0, nr=0;
- for(eve= em->verts.first; eve; eve= eve->next, nr++) {
+ BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
if(nr==hmd->indexar[index]) {
- eve->f |= SELECT;
+ BM_Select(em->bm, eve, 1);
if(index < hmd->totindex-1) index++;
}
+ nr++;
}
- EM_select_flush(em);
-
- BKE_mesh_end_editmesh(me, em);
}
static int return_editlattice_indexar(Lattice *editlatt, int *tot, int **indexar, float *cent)
@@ -1092,16 +1096,13 @@ int hook_getIndexArray(Object *obedit, int *tot, int **indexar, char *name, floa
case OB_MESH:
{
Mesh *me= obedit->data;
- EditMesh *em = BKE_mesh_get_editmesh(me);
+ BMEditMesh *em = me->edit_btmesh;
/* check selected vertices first */
if( return_editmesh_indexar(em, tot, indexar, cent_r)) {
- BKE_mesh_end_editmesh(me, em);
return 1;
} else {
- int ret = return_editmesh_vgroup(obedit, em, name, cent_r);
- BKE_mesh_end_editmesh(me, em);
- return ret;
+ return return_editmesh_vgroup(obedit, em, name, cent_r);
}
}
case OB_CURVE:
@@ -1367,43 +1368,45 @@ void add_hook_menu(Scene *scene, View3D *v3d)
/* ******************** clear parent operator ******************* */
static EnumPropertyItem prop_clear_parent_types[] = {
- {0, "CLEAR", "Clear Parent", ""},
- {1, "CLEAR_KEEP_TRANSFORM", "Clear and Keep Transformation (Clear Track)", ""},
- {2, "CLEAR_INVERSE", "Clear Parent Inverse", ""},
- {0, NULL, NULL, NULL}
+ {0, "CLEAR", 0, "Clear Parent", ""},
+ {1, "CLEAR_KEEP_TRANSFORM", 0, "Clear and Keep Transformation (Clear Track)", ""},
+ {2, "CLEAR_INVERSE", 0, "Clear Parent Inverse", ""},
+ {0, NULL, 0, NULL, NULL}
};
/* note, poll should check for editable scene */
static int parent_clear_exec(bContext *C, wmOperator *op)
{
+ int type= RNA_enum_get(op->ptr, "type");
CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) {
- if(RNA_enum_is_equal(op->ptr, "type", "CLEAR")) {
+ if(type == 0) {
ob->parent= NULL;
}
- if(RNA_enum_is_equal(op->ptr, "type", "CLEAR_KEEP_TRANSFORM")) {
+ else if(type == 1) {
ob->parent= NULL;
ob->track= NULL;
ED_object_apply_obmat(ob);
}
- if(RNA_enum_is_equal(op->ptr, "type", "CLEAR_INVERSE")) {
+ else if(type == 2)
Mat4One(ob->parentinv);
- }
+
ob->recalc |= OB_RECALC;
}
CTX_DATA_END;
DAG_scene_sort(CTX_data_scene(C));
ED_anim_dag_flush_update(C);
-
+ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
+
return OPERATOR_FINISHED;
}
void OBJECT_OT_parent_clear(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Clear parent";
+ ot->name= "Clear Parent";
ot->description = "Clear the object's parenting.";
ot->idname= "OBJECT_OT_parent_clear";
@@ -1423,14 +1426,16 @@ void OBJECT_OT_parent_clear(wmOperatorType *ot)
static EnumPropertyItem prop_clear_track_types[] = {
- {0, "CLEAR", "Clear Track", ""},
- {1, "CLEAR_KEEP_TRANSFORM", "Clear and Keep Transformation (Clear Track)", ""},
- {0, NULL, NULL, NULL}
+ {0, "CLEAR", 0, "Clear Track", ""},
+ {1, "CLEAR_KEEP_TRANSFORM", 0, "Clear and Keep Transformation (Clear Track)", ""},
+ {0, NULL, 0, NULL, NULL}
};
/* note, poll should check for editable scene */
static int object_track_clear_exec(bContext *C, wmOperator *op)
{
+ int type= RNA_enum_get(op->ptr, "type");
+
if(CTX_data_edit_object(C)) {
BKE_report(op->reports, RPT_ERROR, "Operation cannot be performed in EditMode");
return OPERATOR_CANCELLED;
@@ -1439,9 +1444,8 @@ static int object_track_clear_exec(bContext *C, wmOperator *op)
ob->track= NULL;
ob->recalc |= OB_RECALC;
- if(RNA_enum_is_equal(op->ptr, "type", "CLEAR_KEEP_TRANSFORM")) {
+ if(type == 1)
ED_object_apply_obmat(ob);
- }
}
CTX_DATA_END;
@@ -1472,9 +1476,9 @@ void OBJECT_OT_track_clear(wmOperatorType *ot)
/* *****************Selection Operators******************* */
static EnumPropertyItem prop_select_types[] = {
- {0, "EXCLUSIVE", "Exclusive", ""},
- {1, "EXTEND", "Extend", ""},
- {0, NULL, NULL, NULL}
+ {0, "EXCLUSIVE", 0, "Exclusive", ""},
+ {1, "EXTEND", 0, "Extend", ""},
+ {0, NULL, 0, NULL, NULL}
};
/* ****** Select by Type ****** */
@@ -1527,13 +1531,13 @@ void OBJECT_OT_select_by_type(wmOperatorType *ot)
/* ****** selection by links *******/
static EnumPropertyItem prop_select_linked_types[] = {
- {1, "IPO", "Object IPO", ""}, // XXX depreceated animation system stuff...
- {2, "OBDATA", "Ob Data", ""},
- {3, "MATERIAL", "Material", ""},
- {4, "TEXTURE", "Texture", ""},
- {5, "DUPGROUP", "Dupligroup", ""},
- {6, "PARTICLE", "Particle System", ""},
- {0, NULL, NULL, NULL}
+ {1, "IPO", 0, "Object IPO", ""}, // XXX depreceated animation system stuff...
+ {2, "OBDATA", 0, "Ob Data", ""},
+ {3, "MATERIAL", 0, "Material", ""},
+ {4, "TEXTURE", 0, "Texture", ""},
+ {5, "DUPGROUP", 0, "Dupligroup", ""},
+ {6, "PARTICLE", 0, "Particle System", ""},
+ {0, NULL, 0, NULL, NULL}
};
static int object_select_linked_exec(bContext *C, wmOperator *op)
@@ -1684,6 +1688,308 @@ void OBJECT_OT_select_linked(wmOperatorType *ot)
RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select");
}
+
+/* ****** selection grouped *******/
+
+static EnumPropertyItem prop_select_grouped_types[] = {
+ {1, "CHILDREN_RECURSIVE", 0, "Children", ""}, // XXX depreceated animation system stuff...
+ {2, "CHILDREN", 0, "Immediate Children", ""},
+ {3, "PARENT", 0, "Parent", ""},
+ {4, "SIBLINGS", 0, "Siblings", "Shared Parent"},
+ {5, "TYPE", 0, "Type", "Shared object type"},
+ {6, "LAYER", 0, "Layer", "Shared layers"},
+ {7, "GROUP", 0, "Group", "Shared group"},
+ {8, "HOOK", 0, "Hook", ""},
+ {9, "PASS", 0, "Pass", "Render pass Index"},
+ {10, "COLOR", 0, "Color", "Object Color"},
+ {11, "PROPERTIES", 0, "Properties", "Game Properties"},
+ {0, NULL, 0, NULL, NULL}
+};
+
+
+static short select_grouped_children(bContext *C, Object *ob, int recursive)
+{
+ short changed = 0;
+
+ CTX_DATA_BEGIN(C, Base*, base, selectable_bases) {
+ if (ob == base->object->parent) {
+ if (!(base->flag & SELECT)) {
+ ED_base_object_select(base, BA_SELECT);
+ changed = 1;
+ }
+
+ if (recursive)
+ changed |= select_grouped_children(C, base->object, 1);
+ }
+ }
+ CTX_DATA_END;
+ return changed;
+}
+
+static short select_grouped_parent(bContext *C) /* Makes parent active and de-selected OBACT */
+{
+ Scene *scene= CTX_data_scene(C);
+ View3D *v3d= CTX_wm_view3d(C);
+
+ short changed = 0;
+ Base *baspar, *basact= CTX_data_active_base(C);
+
+ if (!basact || !(basact->object->parent)) return 0; /* we know OBACT is valid */
+
+ baspar= object_in_scene(basact->object->parent, scene);
+
+ /* can be NULL if parent in other scene */
+ if(baspar && BASE_SELECTABLE(v3d, baspar)) {
+ ED_base_object_select(basact, BA_DESELECT);
+ ED_base_object_select(baspar, BA_SELECT);
+ ED_base_object_activate(C, baspar);
+ changed = 1;
+ }
+ return changed;
+}
+
+
+#define GROUP_MENU_MAX 24
+static short select_grouped_group(bContext *C, Object *ob) /* Select objects in the same group as the active */
+{
+ short changed = 0;
+ Group *group, *ob_groups[GROUP_MENU_MAX];
+ //char str[10 + (24*GROUP_MENU_MAX)];
+ //char *p = str;
+ int group_count=0; //, menu, i;
+
+ for ( group=G.main->group.first;
+ group && group_count < GROUP_MENU_MAX;
+ group=group->id.next
+ ) {
+ if (object_in_group (ob, group)) {
+ ob_groups[group_count] = group;
+ group_count++;
+ }
+ }
+
+ if (!group_count)
+ return 0;
+
+ else if (group_count == 1) {
+ group = ob_groups[0];
+ CTX_DATA_BEGIN(C, Base*, base, visible_bases) {
+ if (!(base->flag & SELECT) && object_in_group(base->object, group)) {
+ ED_base_object_select(base, BA_SELECT);
+ changed = 1;
+ }
+ }
+ CTX_DATA_END;
+ return changed;
+ }
+#if 0 // XXX hows this work in 2.5?
+ /* build the menu. */
+ p += sprintf(str, "Groups%%t");
+ for (i=0; i<group_count; i++) {
+ group = ob_groups[i];
+ p += sprintf (p, "|%s%%x%i", group->id.name+2, i);
+ }
+
+ menu = pupmenu (str);
+ if (menu == -1)
+ return 0;
+
+ group = ob_groups[menu];
+ for (base= FIRSTBASE; base; base= base->next) {
+ if (!(base->flag & SELECT) && object_in_group(base->object, group)) {
+ ED_base_object_select(base, BA_SELECT);
+ changed = 1;
+ }
+ }
+#endif
+ return changed;
+}
+
+static short select_grouped_object_hooks(bContext *C, Object *ob)
+{
+ Scene *scene= CTX_data_scene(C);
+ View3D *v3d= CTX_wm_view3d(C);
+
+ short changed = 0;
+ Base *base;
+ ModifierData *md;
+ HookModifierData *hmd;
+
+ for (md = ob->modifiers.first; md; md=md->next) {
+ if (md->type==eModifierType_Hook) {
+ hmd= (HookModifierData*) md;
+ if (hmd->object && !(hmd->object->flag & SELECT)) {
+ base= object_in_scene(hmd->object, scene);
+ if (base && (BASE_SELECTABLE(v3d, base))) {
+ ED_base_object_select(base, BA_SELECT);
+ changed = 1;
+ }
+ }
+ }
+ }
+ return changed;
+}
+
+/* Select objects woth the same parent as the active (siblings),
+ * parent can be NULL also */
+static short select_grouped_siblings(bContext *C, Object *ob)
+{
+ short changed = 0;
+
+ CTX_DATA_BEGIN(C, Base*, base, selectable_bases) {
+ if ((base->object->parent==ob->parent) && !(base->flag & SELECT)) {
+ ED_base_object_select(base, BA_SELECT);
+ changed = 1;
+ }
+ }
+ CTX_DATA_END;
+ return changed;
+}
+
+static short select_grouped_type(bContext *C, Object *ob)
+{
+ short changed = 0;
+
+ CTX_DATA_BEGIN(C, Base*, base, selectable_bases) {
+ if ((base->object->type == ob->type) && !(base->flag & SELECT)) {
+ ED_base_object_select(base, BA_SELECT);
+ changed = 1;
+ }
+ }
+ CTX_DATA_END;
+ return changed;
+}
+
+static short select_grouped_layer(bContext *C, Object *ob)
+{
+ char changed = 0;
+
+ CTX_DATA_BEGIN(C, Base*, base, selectable_bases) {
+ if ((base->lay & ob->lay) && !(base->flag & SELECT)) {
+ ED_base_object_select(base, BA_SELECT);
+ changed = 1;
+ }
+ }
+ CTX_DATA_END;
+ return changed;
+}
+
+static short select_grouped_index_object(bContext *C, Object *ob)
+{
+ char changed = 0;
+
+ CTX_DATA_BEGIN(C, Base*, base, selectable_bases) {
+ if ((base->object->index == ob->index) && !(base->flag & SELECT)) {
+ ED_base_object_select(base, BA_SELECT);
+ changed = 1;
+ }
+ }
+ CTX_DATA_END;
+ return changed;
+}
+
+static short select_grouped_color(bContext *C, Object *ob)
+{
+ char changed = 0;
+
+ CTX_DATA_BEGIN(C, Base*, base, selectable_bases) {
+ if (!(base->flag & SELECT) && (FloatCompare(base->object->col, ob->col, 0.005f))) {
+ ED_base_object_select(base, BA_SELECT);
+ changed = 1;
+ }
+ }
+ CTX_DATA_END;
+ return changed;
+}
+
+static short objects_share_gameprop(Object *a, Object *b)
+{
+ bProperty *prop;
+ /*make a copy of all its properties*/
+
+ for( prop= a->prop.first; prop; prop = prop->next ) {
+ if ( get_ob_property(b, prop->name) )
+ return 1;
+ }
+ return 0;
+}
+
+static short select_grouped_gameprops(bContext *C, Object *ob)
+{
+ char changed = 0;
+
+ CTX_DATA_BEGIN(C, Base*, base, selectable_bases) {
+ if (!(base->flag & SELECT) && (objects_share_gameprop(base->object, ob))) {
+ ED_base_object_select(base, BA_SELECT);
+ changed = 1;
+ }
+ }
+ CTX_DATA_END;
+ return changed;
+}
+
+static int object_select_grouped_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene= CTX_data_scene(C);
+ Object *ob;
+ int nr = RNA_enum_get(op->ptr, "type");
+ short changed = 0, seltype;
+
+ seltype = RNA_enum_get(op->ptr, "seltype");
+
+ if (seltype == 0) {
+ CTX_DATA_BEGIN(C, Base*, base, visible_bases) {
+ ED_base_object_select(base, BA_DESELECT);
+ }
+ CTX_DATA_END;
+ }
+
+ ob= OBACT;
+ if(ob==0){
+ BKE_report(op->reports, RPT_ERROR, "No Active Object");
+ return OPERATOR_CANCELLED;
+ }
+
+ if(nr==1) changed = select_grouped_children(C, ob, 1);
+ else if(nr==2) changed = select_grouped_children(C, ob, 0);
+ else if(nr==3) changed = select_grouped_parent(C);
+ else if(nr==4) changed = select_grouped_siblings(C, ob);
+ else if(nr==5) changed = select_grouped_type(C, ob);
+ else if(nr==6) changed = select_grouped_layer(C, ob);
+ else if(nr==7) changed = select_grouped_group(C, ob);
+ else if(nr==8) changed = select_grouped_object_hooks(C, ob);
+ else if(nr==9) changed = select_grouped_index_object(C, ob);
+ else if(nr==10) changed = select_grouped_color(C, ob);
+ else if(nr==11) changed = select_grouped_gameprops(C, ob);
+
+ if (changed) {
+ WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C));
+ return OPERATOR_FINISHED;
+ }
+
+ return OPERATOR_CANCELLED;
+}
+
+void OBJECT_OT_select_grouped(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Select Grouped";
+ ot->description = "Select all visible objects grouped by various properties.";
+ ot->idname= "OBJECT_OT_select_grouped";
+
+ /* api callbacks */
+ ot->invoke= WM_menu_invoke;
+ ot->exec= object_select_grouped_exec;
+ ot->poll= ED_operator_scene_editable;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ RNA_def_enum(ot->srna, "type", prop_select_grouped_types, 0, "Type", "");
+ RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select");
+
+}
+
/* ****** selection by layer *******/
static int object_select_by_layer_exec(bContext *C, wmOperator *op)
@@ -1733,7 +2039,7 @@ void OBJECT_OT_select_by_layer(wmOperatorType *ot)
}
/* ****** invert selection *******/
-static int object_select_invert_exec(bContext *C, wmOperator *op)
+static int object_select_inverse_exec(bContext *C, wmOperator *op)
{
CTX_DATA_BEGIN(C, Base*, base, visible_bases) {
if (base->flag & SELECT)
@@ -1749,16 +2055,16 @@ static int object_select_invert_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void OBJECT_OT_select_invert(wmOperatorType *ot)
+void OBJECT_OT_select_inverse(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Invert selection";
- ot->description = "Invert th select of all visible objects.";
- ot->idname= "OBJECT_OT_select_invert";
+ ot->name= "Select Inverse";
+ ot->description = "Invert selection of all visible objects.";
+ ot->idname= "OBJECT_OT_select_inverse";
/* api callbacks */
- ot->exec= object_select_invert_exec;
+ ot->exec= object_select_inverse_exec;
ot->poll= ED_operator_scene_editable;
/* flags */
@@ -1891,7 +2197,7 @@ void OBJECT_OT_location_clear(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Clear Object Location";
+ ot->name= "Clear Location";
ot->description = "Clear the object's location.";
ot->idname= "OBJECT_OT_location_clear";
@@ -1935,7 +2241,7 @@ void OBJECT_OT_rotation_clear(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Clear Object Rotation";
+ ot->name= "Clear Rotation";
ot->description = "Clear the object's rotation.";
ot->idname= "OBJECT_OT_rotation_clear";
@@ -1983,7 +2289,7 @@ void OBJECT_OT_scale_clear(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Clear Object Scale";
+ ot->name= "Clear Scale";
ot->description = "Clear the object's scale.";
ot->idname= "OBJECT_OT_scale_clear";
@@ -2029,7 +2335,7 @@ void OBJECT_OT_origin_clear(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Clear Object Origin";
+ ot->name= "Clear Origin";
ot->description = "Clear the object's origin.";
ot->idname= "OBJECT_OT_origin_clear";
@@ -2072,12 +2378,11 @@ void OBJECT_OT_restrictview_clear(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Clear restrict view";
+ ot->name= "Clear Restrict View";
ot->description = "Reveal the object by setting the restrictview flag.";
ot->idname= "OBJECT_OT_restrictview_clear";
/* api callbacks */
- ot->invoke= WM_operator_confirm;
ot->exec= object_restrictview_clear_exec;
ot->poll= ED_operator_view3d_active;
@@ -2085,19 +2390,14 @@ void OBJECT_OT_restrictview_clear(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
-static EnumPropertyItem prop_set_restrictview_types[] = {
- {0, "SELECTED", "Selected", ""},
- {1, "UNSELECTED", "Unselected ", ""},
- {0, NULL, NULL, NULL}
-};
-
static int object_restrictview_set_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
short changed = 0;
+ int unselected= RNA_boolean_get(op->ptr, "unselected");
CTX_DATA_BEGIN(C, Base*, base, visible_bases) {
- if(RNA_enum_is_equal(op->ptr, "type", "SELECTED")){
+ if(!unselected) {
if (base->flag & SELECT){
base->flag &= ~SELECT;
base->object->flag = base->flag;
@@ -2108,7 +2408,7 @@ static int object_restrictview_set_exec(bContext *C, wmOperator *op)
}
}
}
- else if (RNA_enum_is_equal(op->ptr, "type", "UNSELECTED")){
+ else {
if (!(base->flag & SELECT)){
base->object->restrictflag |= OB_RESTRICT_VIEW;
changed = 1;
@@ -2130,19 +2430,18 @@ static int object_restrictview_set_exec(bContext *C, wmOperator *op)
void OBJECT_OT_restrictview_set(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Set restrict view";
+ ot->name= "Set Restrict View";
ot->description = "Hide the object by setting the restrictview flag.";
ot->idname= "OBJECT_OT_restrictview_set";
/* api callbacks */
- ot->invoke= WM_menu_invoke;
ot->exec= object_restrictview_set_exec;
ot->poll= ED_operator_view3d_active;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
- RNA_def_enum(ot->srna, "type", prop_set_restrictview_types, 0, "Type", "");
+ RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected objects.");
}
/* ************* Slow Parent ******************* */
@@ -2240,10 +2539,10 @@ void make_vertex_parent(Scene *scene, Object *obedit, View3D *v3d)
if(obedit->type==OB_MESH) {
Mesh *me= obedit->data;
- EditMesh *em = BKE_mesh_get_editmesh(me);
+ BMEditMesh *em = me->edit_btmesh;
+ BMIter iter;
- eve= em->verts.first;
- while(eve) {
+ BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
if(eve->f & 1) {
if(v1==0) v1= nr;
else if(v2==0) v2= nr;
@@ -2252,10 +2551,7 @@ void make_vertex_parent(Scene *scene, Object *obedit, View3D *v3d)
else break;
}
nr++;
- eve= eve->next;
}
-
- BKE_mesh_end_editmesh(me, em);
}
else if(ELEM(obedit->type, OB_SURF, OB_CURVE)) {
ListBase *editnurb= curve_get_editcurve(obedit);
@@ -2463,16 +2759,16 @@ void make_proxy(Scene *scene)
#define PAR_TRIA 8
static EnumPropertyItem prop_make_parent_types[] = {
- {PAR_OBJECT, "OBJECT", "Object", ""},
- {PAR_ARMATURE, "ARMATURE", "Armature Deform", ""},
- {PAR_BONE, "BONE", "Bone", ""},
- {PAR_CURVE, "CURVE", "Curve Deform", ""},
- {PAR_FOLLOW, "FOLLOW", "Follow Path", ""},
- {PAR_PATH_CONST, "PATH_CONST", "Path Constraint", ""},
- {PAR_LATTICE, "LATTICE", "Lattice Deform", ""},
- {PAR_VERTEX, "VERTEX", "Vertex", ""},
- {PAR_TRIA, "TRIA", "Triangle", ""},
- {0, NULL, NULL, NULL}
+ {PAR_OBJECT, "OBJECT", 0, "Object", ""},
+ {PAR_ARMATURE, "ARMATURE", 0, "Armature Deform", ""},
+ {PAR_BONE, "BONE", 0, "Bone", ""},
+ {PAR_CURVE, "CURVE", 0, "Curve Deform", ""},
+ {PAR_FOLLOW, "FOLLOW", 0, "Follow Path", ""},
+ {PAR_PATH_CONST, "PATH_CONST", 0, "Path Constraint", ""},
+ {PAR_LATTICE, "LATTICE", 0, "Lattice Deform", ""},
+ {PAR_VERTEX, "VERTEX", 0, "Vertex", ""},
+ {PAR_TRIA, "TRIA", 0, "Triangle", ""},
+ {0, NULL, 0, NULL, NULL}
};
static int test_parent_loop(Object *par, Object *ob)
@@ -2601,7 +2897,8 @@ static int parent_set_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
DAG_scene_sort(CTX_data_scene(C));
- ED_anim_dag_flush_update(C);
+ ED_anim_dag_flush_update(C);
+ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
return OPERATOR_FINISHED;
}
@@ -2638,7 +2935,7 @@ static int parent_set_invoke(bContext *C, wmOperator *op, wmEvent *event)
void OBJECT_OT_parent_set(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Make parent";
+ ot->name= "Make Parent";
ot->description = "Set the object's parenting.";
ot->idname= "OBJECT_OT_parent_set";
@@ -2649,24 +2946,25 @@ void OBJECT_OT_parent_set(wmOperatorType *ot)
ot->poll= ED_operator_object_active;
/* flags */
- ot->flag= 0;
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
RNA_def_enum(ot->srna, "type", prop_make_parent_types, 0, "Type", "");
}
/* *** make track ***** */
static EnumPropertyItem prop_make_track_types[] = {
- {1, "TRACKTO", "TrackTo Constraint", ""},
- {2, "LOCKTRACK", "LockTrack Constraint", ""},
- {3, "OLDTRACK", "Old Track", ""},
- {0, NULL, NULL, NULL}
+ {1, "TRACKTO", 0, "TrackTo Constraint", ""},
+ {2, "LOCKTRACK", 0, "LockTrack Constraint", ""},
+ {3, "OLDTRACK", 0, "Old Track", ""},
+ {0, NULL, 0, NULL, NULL}
};
static int track_set_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
+ int type= RNA_enum_get(op->ptr, "type");
- if(RNA_enum_is_equal(op->ptr, "type", "TRACKTO")){
+ if(type == 1) {
bConstraint *con;
bTrackToConstraint *data;
@@ -2690,7 +2988,7 @@ static int track_set_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
}
- else if(RNA_enum_is_equal(op->ptr, "type", "LOCKTRACK")){
+ else if(type == 2) {
bConstraint *con;
bLockTrackConstraint *data;
@@ -2714,7 +3012,7 @@ static int track_set_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
}
- else if(RNA_enum_is_equal(op->ptr, "type", "OLDTRACK")){
+ else {
CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
if(base!=BASACT) {
base->object->track= BASACT->object;
@@ -2792,7 +3090,7 @@ static void make_object_duplilist_real(Scene *scene, View3D *v3d, Base *base)
}
-static int object_dupli_set_real_exec(bContext *C, wmOperator *op)
+static int object_duplicates_make_real_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
ScrArea *sa= CTX_wm_area(C);
@@ -2812,17 +3110,17 @@ static int object_dupli_set_real_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void OBJECT_OT_dupli_set_real(wmOperatorType *ot)
+void OBJECT_OT_duplicates_make_real(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Make Dupli Real";
+ ot->name= "Make Duplicates Real";
ot->description = "Make dupli objects attached to this object real.";
- ot->idname= "OBJECT_OT_dupli_set_real";
+ ot->idname= "OBJECT_OT_duplicates_make_real";
/* api callbacks */
ot->invoke= WM_operator_confirm;
- ot->exec= object_dupli_set_real_exec;
+ ot->exec= object_duplicates_make_real_exec;
ot->poll= ED_operator_scene_editable;
@@ -2832,10 +3130,10 @@ void OBJECT_OT_dupli_set_real(wmOperatorType *ot)
/* ******************* Set Object Center ********************** */
static EnumPropertyItem prop_set_center_types[] = {
- {0, "CENTER", "ObData to Center", "Move object data around Object center"},
- {1, "CENTERNEW", "Center New", "Move Object center to center of object data"},
- {2, "CENTERCURSOR", "Center Cursor", "Move Object Center to position of the 3d cursor"},
- {0, NULL, NULL, NULL}
+ {0, "CENTER", 0, "ObData to Center", "Move object data around Object center"},
+ {1, "CENTERNEW", 0, "Center New", "Move Object center to center of object data"},
+ {2, "CENTERCURSOR", 0, "Center Cursor", "Move Object Center to position of the 3d cursor"},
+ {0, NULL, 0, NULL, NULL}
};
/* 0 == do center, 1 == center new, 2 == center cursor */
@@ -2876,9 +3174,10 @@ static int object_center_set_exec(bContext *C, wmOperator *op)
if(obedit->type==OB_MESH) {
Mesh *me= obedit->data;
- EditMesh *em = BKE_mesh_get_editmesh(me);
+ BMEditMesh *em = me->edit_btmesh;
+ BMIter iter;
- for(eve= em->verts.first; eve; eve= eve->next) {
+ BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
if(v3d->around==V3D_CENTROID) {
total++;
VECADD(cent, cent, eve->co);
@@ -2897,14 +3196,13 @@ static int object_center_set_exec(bContext *C, wmOperator *op)
cent[2]= (min[2]+max[2])/2.0f;
}
- for(eve= em->verts.first; eve; eve= eve->next) {
+ BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
VecSubf(eve->co, eve->co, cent);
}
- recalc_editnormals(em);
+ EDBM_RecalcNormals(em);
tot_change++;
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
- BKE_mesh_end_editmesh(me, em);
}
}
@@ -3208,7 +3506,11 @@ void ED_object_exit_editmode(bContext *C, int flag)
EDBM_LoadEditBMesh(scene, obedit);
- if(freedata) EDBM_FreeEditBMesh(me->edit_btmesh);
+ if(freedata) {
+ EDBM_FreeEditBMesh(me->edit_btmesh);
+ MEM_freeN(me->edit_btmesh);
+ me->edit_btmesh= NULL;
+ }
if(G.f & G_WEIGHTPAINT)
mesh_octree_table(obedit, NULL, NULL, 'e');
@@ -3257,7 +3559,7 @@ void ED_object_enter_editmode(bContext *C, int flag)
{
Scene *scene= CTX_data_scene(C);
Base *base= CTX_data_active_base(C);
- Object *ob= base->object;
+ Object *ob;
ScrArea *sa= CTX_wm_area(C);
View3D *v3d= NULL;
int ok= 0;
@@ -3269,7 +3571,10 @@ void ED_object_enter_editmode(bContext *C, int flag)
v3d= sa->spacedata.first;
if((v3d==NULL || (base->lay & v3d->lay))==0) return;
-
+
+ ob = base->object;
+
+ if(ob==NULL) return;
if(ob->data==NULL) return;
if (object_data_is_libdata(ob)) {
@@ -3351,6 +3656,7 @@ void ED_object_enter_editmode(bContext *C, int flag)
WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, scene);
}
+ if(flag & EM_DO_UNDO) ED_undo_push(C, "Enter Editmode");
if(flag & EM_WAITCURSOR) waitcursor(0);
}
@@ -3574,9 +3880,7 @@ void special_editmenu(Scene *scene, View3D *v3d)
// XXX static short numcuts= 2;
Object *ob= OBACT;
Object *obedit= NULL; // XXX
- float fac;
int nr,ret=0;
- short randfac;
if(ob==NULL) return;
@@ -3663,7 +3967,7 @@ void special_editmenu(Scene *scene, View3D *v3d)
if(!psys)
return;
- if(scene->selectmode & SCE_SELECT_POINT)
+ if(pset->selectmode & SCE_SELECT_POINT)
nr= pupmenu("Specials%t|Rekey%x1|Subdivide%x2|Select First%x3|Select Last%x4|Remove Doubles%x5");
else
nr= pupmenu("Specials%t|Rekey%x1|Remove Doubles%x5");
@@ -3765,144 +4069,8 @@ void special_editmenu(Scene *scene, View3D *v3d)
}
}
else if(obedit->type==OB_MESH) {
- /* This is all that is needed, since all other functionality is in Ctrl+ V/E/F but some users didnt like, so for now have the old/big menu */
- /*
- nr= pupmenu("Subdivide Mesh%t|Subdivide%x1|Subdivide Multi%x2|Subdivide Multi Fractal%x3|Subdivide Smooth%x4");
- switch(nr) {
- case 1:
- waitcursor(1);
- esubdivideflag(1, 0.0, scene->toolsettings->editbutflag, 1, 0);
-
- break;
- case 2:
- if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return;
- waitcursor(1);
- esubdivideflag(1, 0.0, scene->toolsettings->editbutflag, numcuts, 0);
- break;
- case 3:
- if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return;
- randfac= 10;
- if(button(&randfac, 1, 100, "Rand fac:")==0) return;
- waitcursor(1);
- fac= -( (float)randfac )/100;
- esubdivideflag(1, fac, scene->toolsettings->editbutflag, numcuts, 0);
- break;
-
- case 4:
- fac= 1.0f;
- if(fbutton(&fac, 0.0f, 5.0f, 10, 10, "Smooth:")==0) return;
- fac= 0.292f*fac;
-
- waitcursor(1);
- esubdivideflag(1, fac, scene->toolsettings->editbutflag | B_SMOOTH, 1, 0);
- break;
- }
- */
-
- nr= pupmenu("Specials%t|Subdivide%x1|Subdivide Multi%x2|Subdivide Multi Fractal%x3|Subdivide Smooth%x12|Merge%x4|Remove Doubles%x5|Hide%x6|Reveal%x7|Select Swap%x8|Flip Normals %x9|Smooth %x10|Bevel %x11|Set Smooth %x14|Set Solid %x15|Blend From Shape%x16|Propagate To All Shapes%x17|Select Vertex Path%x18");
-
- switch(nr) {
- case 1:
- waitcursor(1);
-// XXX esubdivideflag(1, 0.0, scene->toolsettings->editbutflag, 1, 0);
-
- break;
- case 2:
-// XXX if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return;
- waitcursor(1);
-// XXX esubdivideflag(1, 0.0, scene->toolsettings->editbutflag, numcuts, 0);
- break;
- case 3:
-// XXX if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return;
- randfac= 10;
-// XXX if(button(&randfac, 1, 100, "Rand fac:")==0) return;
- waitcursor(1);
- fac= -( (float)randfac )/100;
-// XXX esubdivideflag(1, fac, scene->toolsettings->editbutflag, numcuts, 0);
- break;
-
- case 12: /* smooth */
- /* if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return; */
- fac= 1.0f;
-// XXX if(fbutton(&fac, 0.0f, 5.0f, 10, 10, "Smooth:")==0) return;
-// XXX fac= 0.292f*fac;
-
- waitcursor(1);
-// XXX esubdivideflag(1, fac, scene->toolsettings->editbutflag | B_SMOOTH, 1, 0);
- break;
-
- case 4:
-// XXX mergemenu();
- break;
- case 5:
-// XXX notice("Removed %d Vertices", removedoublesflag(1, 0, scene->toolsettings->doublimit));
- break;
- case 6:
-// XXX hide_mesh(0);
- break;
- case 7:
-// XXX reveal_mesh();
- break;
- case 8:
-// XXX selectswap_mesh();
- break;
- case 9:
-// XXX flip_editnormals();
- break;
- case 10:
-// XXX vertexsmooth();
- break;
- case 11:
-// XXX bevel_menu();
- break;
- case 14:
-// XXX mesh_set_smooth_faces(1);
- break;
- case 15:
-// XXX mesh_set_smooth_faces(0);
- break;
- case 16:
-// XXX shape_copy_select_from();
- break;
- case 17:
-// XXX shape_propagate();
- break;
- case 18:
-// XXX pathselect();
- break;
- }
-
-
- DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-
- if(nr>0) waitcursor(0);
-
}
else if(ELEM(obedit->type, OB_CURVE, OB_SURF)) {
-
- nr= pupmenu("Specials%t|Subdivide%x1|Switch Direction%x2|Set Goal Weight%x3|Set Radius%x4|Smooth%x5|Smooth Radius%x6");
-
- switch(nr) {
- case 1:
-// XXX subdivideNurb();
- break;
- case 2:
-// XXX switchdirectionNurb2();
- break;
- case 3:
-// XXX setweightNurb();
- break;
- case 4:
-// XXX setradiusNurb();
- break;
- case 5:
-// XXX smoothNurb();
- break;
- case 6:
-// XXX smoothradiusNurb();
- break;
- }
- DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
}
else if(obedit->type==OB_ARMATURE) {
nr= pupmenu("Specials%t|Subdivide %x1|Subdivide Multi%x2|Switch Direction%x7|Flip Left-Right Names%x3|%l|AutoName Left-Right%x4|AutoName Front-Back%x5|AutoName Top-Bottom%x6");
@@ -6088,11 +6256,12 @@ Base *ED_object_add_duplicate(Scene *scene, Base *base, int usedupflag)
}
/* contextual operator dupli */
-static int duplicate_add_exec(bContext *C, wmOperator *op)
+static int duplicate_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
View3D *v3d= CTX_wm_view3d(C);
- int dupflag= U.dupflag;
+ int linked= RNA_boolean_get(op->ptr, "linked");
+ int dupflag= (linked)? 0: U.dupflag;
clear_id_newpoins();
clear_sca_new_poins(); /* sensor/contr/act */
@@ -6120,9 +6289,9 @@ static int duplicate_add_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int duplicate_add_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int duplicate_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
- duplicate_add_exec(C, op);
+ duplicate_exec(C, op);
RNA_int_set(op->ptr, "mode", TFM_TRANSLATION);
WM_operator_name_call(C, "TFM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr);
@@ -6130,17 +6299,17 @@ static int duplicate_add_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_FINISHED;
}
-void OBJECT_OT_duplicate_add(wmOperatorType *ot)
+void OBJECT_OT_duplicate(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Add Duplicate";
- ot->description = "Duplicate the object.";
- ot->idname= "OBJECT_OT_duplicate_add";
+ ot->name= "Duplicate";
+ ot->description = "Duplicate selected objects.";
+ ot->idname= "OBJECT_OT_duplicate";
/* api callbacks */
- ot->invoke= duplicate_add_invoke;
- ot->exec= duplicate_add_exec;
+ ot->invoke= duplicate_invoke;
+ ot->exec= duplicate_exec;
ot->poll= ED_operator_scene_editable;
@@ -6148,9 +6317,57 @@ void OBJECT_OT_duplicate_add(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* to give to transform */
+ RNA_def_boolean(ot->srna, "linked", 0, "Linked", "Duplicate object but not object data, linking to the original data.");
RNA_def_int(ot->srna, "mode", TFM_TRANSLATION, 0, INT_MAX, "Mode", "", 0, INT_MAX);
}
+/* ************************** JOIN *********************** */
+
+static int join_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene= CTX_data_scene(C);
+ Object *ob= CTX_data_active_object(C);
+
+ if(scene->obedit) {
+ BKE_report(op->reports, RPT_ERROR, "This data does not support joining in editmode.");
+ return OPERATOR_CANCELLED;
+ }
+ else if(!ob) {
+ BKE_report(op->reports, RPT_ERROR, "Can't join unless there is an active object.");
+ return OPERATOR_CANCELLED;
+ }
+ else if(object_data_is_libdata(ob)) {
+ BKE_report(op->reports, RPT_ERROR, "Can't edit external libdata.");
+ return OPERATOR_CANCELLED;
+ }
+
+ if(ob->type == OB_MESH)
+ return join_mesh_exec(C, op);
+ else if(ELEM(ob->type, OB_CURVE, OB_SURF))
+ return join_curve_exec(C, op);
+ else if(ob->type == OB_ARMATURE)
+ return join_armature_exec(C, op);
+
+ BKE_report(op->reports, RPT_ERROR, "This object type doesn't support joining.");
+
+ return OPERATOR_CANCELLED;
+}
+
+void OBJECT_OT_join(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Join";
+ ot->description = "Join selected objects into active object.";
+ ot->idname= "OBJECT_OT_join";
+
+ /* api callbacks */
+ ot->exec= join_exec;
+ ot->poll= ED_operator_scene_editable;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
/* ********************** */
void image_aspect(Scene *scene, View3D *v3d)