diff options
Diffstat (limited to 'source/blender/editors/mesh')
-rw-r--r-- | source/blender/editors/mesh/SConscript | 7 | ||||
-rw-r--r-- | source/blender/editors/mesh/bmesh_select.c | 116 | ||||
-rw-r--r-- | source/blender/editors/mesh/bmesh_tools.c | 74 | ||||
-rw-r--r-- | source/blender/editors/mesh/editface.c | 61 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh.c | 21 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_add.c | 240 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_mods.c | 27 | ||||
-rw-r--r-- | source/blender/editors/mesh/loopcut.c | 65 | ||||
-rw-r--r-- | source/blender/editors/mesh/mesh_data.c (renamed from source/blender/editors/mesh/mesh_layers.c) | 446 | ||||
-rw-r--r-- | source/blender/editors/mesh/mesh_intern.h | 8 | ||||
-rw-r--r-- | source/blender/editors/mesh/mesh_ops.c | 237 | ||||
-rw-r--r-- | source/blender/editors/mesh/meshtools.c | 4 |
12 files changed, 717 insertions, 589 deletions
diff --git a/source/blender/editors/mesh/SConscript b/source/blender/editors/mesh/SConscript index 80536b5e431..ac46ee157cc 100644 --- a/source/blender/editors/mesh/SConscript +++ b/source/blender/editors/mesh/SConscript @@ -9,4 +9,11 @@ incs += ' #/intern/guardedalloc ../../gpu' incs += ' ../../makesrna ../../render/extern/include #/intern/elbeem/extern' incs += ' ../../bmesh ' +if env['OURPLATFORM'] == 'linux2': + cflags='-pthread' + incs += ' ../../../extern/binreloc/include' + +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): + incs += ' ' + env['BF_PTHREADS_INC'] + env.BlenderLib ( 'bf_editors_mesh', sources, Split(incs), [], libtype=['core'], priority=[45] ) diff --git a/source/blender/editors/mesh/bmesh_select.c b/source/blender/editors/mesh/bmesh_select.c index af48457a2ff..3e1d5034328 100644 --- a/source/blender/editors/mesh/bmesh_select.c +++ b/source/blender/editors/mesh/bmesh_select.c @@ -87,6 +87,8 @@ BMEditMesh_mods.c, UI level access, no geometry changes #include "BIF_gl.h" #include "BIF_glutil.h" +#include "UI_resources.h" + #include "mesh_intern.h" #include "BLO_sys_types.h" // for intptr_t support @@ -116,22 +118,24 @@ void EDBM_select_mirrored(Object *obedit, BMEditMesh *em) #endif } -void EDBM_automerge(int update) +void EDBM_automerge(Scene *scene, Object *obedit, int update) { -// XXX int len; - -// if ((scene->automerge) && -// (obedit && obedit->type==OB_MESH) && -// (((Mesh*)obedit->data)->mr==NULL) -// ) { -// len = removedoublesflag(1, 1, scene->toolsettings->doublimit); -// if (len) { -// em->totvert -= len; /* saves doing a countall */ -// if (update) { -// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); -// } -// } -// } + BMEditMesh *em; + int len; + + if ((scene->toolsettings->automerge) && + (obedit && obedit->type==OB_MESH) && + (((Mesh*)obedit->data)->mr==NULL)) + { + em = ((Mesh*)obedit->data)->edit_btmesh; + if (!em) + return; + + BMO_CallOpf(em->bm, "automerge verts=%hv dist=%f", BM_SELECT, scene->toolsettings->doublimit); + if (update) { + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + } + } } /* ****************************** SELECTION ROUTINES **************** */ @@ -417,6 +421,9 @@ BMVert *EDBM_findnearestvert(ViewContext *vc, int *dist, short sel, short strict data.closestIndex = 0; data.pass = 0; + + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); + mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, 1); if (data.dist>3) { @@ -505,6 +512,7 @@ BMEdge *EDBM_findnearestedge(ViewContext *vc, int *dist) data.mval[1] = vc->mval[1]; data.dist = *dist; data.closest = NULL; + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); mesh_foreachScreenEdge(vc, findnearestedge__doClosest, &data, 2); @@ -588,12 +596,14 @@ BMFace *EDBM_findnearestface(ViewContext *vc, int *dist) data.dist = *dist; data.closest = NULL; data.closestIndex = 0; + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); data.pass = 0; mesh_foreachScreenFace(vc, findnearestface__doClosest, &data); if (data.dist>3) { data.pass = 1; + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); mesh_foreachScreenFace(vc, findnearestface__doClosest, &data); } @@ -644,20 +654,31 @@ static int unified_findnearest(ViewContext *vc, BMVert **eve, BMEdge **eed, BMFa /* **************** SIMILAR "group" SELECTS. FACE, EDGE AND VERTEX ************** */ -/* selects new faces/edges/verts based on the existing selection */ +static EnumPropertyItem prop_similar_types[] = { + {SIMVERT_NORMAL, "NORMAL", 0, "Normal", ""}, + {SIMVERT_FACE, "FACE", 0, "Amount of Adjacent Faces", ""}, + {SIMVERT_VGROUP, "VGROUP", 0, "Vertex Groups", ""}, -/* FACES GROUP */ + {SIMEDGE_LENGTH, "LENGTH", 0, "Length", ""}, + {SIMEDGE_DIR, "DIR", 0, "Direction", ""}, + {SIMEDGE_FACE, "FACE", 0, "Amount of Faces Around an Edge", ""}, + {SIMEDGE_FACE_ANGLE, "FACE_ANGLE", 0, "Face Angles", ""}, + {SIMEDGE_CREASE, "CREASE", 0, "Crease", ""}, + {SIMEDGE_SEAM, "SEAM", 0, "Seam", ""}, + {SIMEDGE_SHARP, "SHARP", 0, "Sharpness", ""}, -static EnumPropertyItem prop_simface_types[] = { {SIMFACE_MATERIAL, "MATERIAL", 0, "Material", ""}, {SIMFACE_IMAGE, "IMAGE", 0, "Image", ""}, {SIMFACE_AREA, "AREA", 0, "Area", ""}, {SIMFACE_PERIMETER, "PERIMETER", 0, "Perimeter", ""}, {SIMFACE_NORMAL, "NORMAL", 0, "Normal", ""}, {SIMFACE_COPLANAR, "COPLANAR", 0, "Co-planar", ""}, + {0, NULL, 0, NULL, NULL} }; +/* selects new faces/edges/verts based on the existing selection */ + static int similar_face_select_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); @@ -698,17 +719,6 @@ static int similar_face_select_exec(bContext *C, wmOperator *op) /* EDGE GROUP */ -static EnumPropertyItem prop_simedge_types[] = { - {SIMEDGE_LENGTH, "LENGTH", 0, "Length", ""}, - {SIMEDGE_DIR, "DIR", 0, "Direction", ""}, - {SIMEDGE_FACE, "FACE", 0, "Amount of Faces Around an Edge", ""}, - {SIMEDGE_FACE_ANGLE, "FACE_ANGLE", 0, "Face Angles", ""}, - {SIMEDGE_CREASE, "CREASE", 0, "Crease", ""}, - {SIMEDGE_SEAM, "SEAM", 0, "Seam", ""}, - {SIMEDGE_SHARP, "SHARP", 0, "Sharpness", ""}, - {0, NULL, 0, NULL, NULL} -}; - /* wrap the above function but do selection flushing edge to face */ static int similar_edge_select_exec(bContext *C, wmOperator *op) { @@ -756,13 +766,6 @@ VERT GROUP mode 3: same vertex groups */ -static EnumPropertyItem prop_simvertex_types[] = { - {SIMVERT_NORMAL, "NORMAL", 0, "Normal", ""}, - {SIMVERT_FACE, "FACE", 0, "Amount of Adjacent Faces", ""}, - {SIMVERT_VGROUP, "VGROUP", 0, "Vertex Groups", ""}, - {0, NULL, 0, NULL, NULL} -}; - static int similar_vert_select_exec(bContext *C, wmOperator *op) { @@ -814,32 +817,26 @@ static int select_similar_exec(bContext *C, wmOperator *op) static EnumPropertyItem *select_similar_type_itemf(bContext *C, PointerRNA *ptr, int *free) { - Object *obedit; + Object *obedit = CTX_data_edit_object(C); EnumPropertyItem *item= NULL; - int totitem= 0; - - if(C==NULL) { - /* needed for doc generation */ - RNA_enum_items_add(&item, &totitem, prop_simvertex_types); - RNA_enum_items_add(&item, &totitem, prop_simedge_types); - RNA_enum_items_add(&item, &totitem, prop_simface_types); - RNA_enum_item_end(&item, &totitem); - *free= 1; - - return item; - } - - obedit= CTX_data_edit_object(C); + int a, totitem= 0; if(obedit && obedit->type == OB_MESH) { BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh; - if(em->selectmode & SCE_SELECT_VERTEX) - RNA_enum_items_add(&item, &totitem, prop_simvertex_types); - else if(em->selectmode & SCE_SELECT_EDGE) - RNA_enum_items_add(&item, &totitem, prop_simedge_types); - else if(em->selectmode & SCE_SELECT_FACE) - RNA_enum_items_add(&item, &totitem, prop_simface_types); + if(em->selectmode & SCE_SELECT_VERTEX) { + for (a=SIMVERT_NORMAL; a<SIMEDGE_LENGTH; a++) { + RNA_enum_items_add_value(&item, &totitem, prop_similar_types, a); + } + } else if(em->selectmode & SCE_SELECT_EDGE) { + for (a=SIMEDGE_LENGTH; a<SIMFACE_MATERIAL; a++) { + RNA_enum_items_add_value(&item, &totitem, prop_similar_types, a); + } + } else if(em->selectmode & SCE_SELECT_FACE) { + for (a=SIMFACE_MATERIAL; a<=SIMFACE_COPLANAR; a++) { + RNA_enum_items_add_value(&item, &totitem, prop_similar_types, a); + } + } RNA_enum_item_end(&item, &totitem); *free= 1; @@ -868,7 +865,7 @@ void MESH_OT_select_similar(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - prop= RNA_def_enum(ot->srna, "type", prop_simvertex_types, 0, "Type", ""); + prop= RNA_def_enum(ot->srna, "type", prop_similar_types, SIMVERT_NORMAL, "Type", ""); RNA_def_enum_funcs(prop, select_similar_type_itemf); } @@ -1134,6 +1131,9 @@ static void mouse_mesh_loop(bContext *C, short mval[2], short extend, short ring vc.mval[1]= mval[1]; em= vc.em; + /* no afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad */ + view3d_validate_backbuf(&vc); + eed= EDBM_findnearestedge(&vc, &dist); if(eed) { if(extend==0) EDBM_clear_flag_all(em, BM_SELECT); diff --git a/source/blender/editors/mesh/bmesh_tools.c b/source/blender/editors/mesh/bmesh_tools.c index eb1c84a382f..9b31a06edb3 100644 --- a/source/blender/editors/mesh/bmesh_tools.c +++ b/source/blender/editors/mesh/bmesh_tools.c @@ -2672,7 +2672,7 @@ void MESH_OT_remove_doubles(wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - RNA_def_float(ot->srna, "mergedist", 0.0001, 0.0001, 100.0, + RNA_def_float(ot->srna, "mergedist", 0.0001f, 0.000001f, 50.0f, "Merge Distance", "Minimum distance between elements to merge.", 0.00001, 10.0); } @@ -2985,24 +2985,70 @@ static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event) else BMINDEX_SET(e, 0); } - /*expand edge selection*/ - BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { + /*handle case of one vert selected. we identify + the closest edge around that vert to the mouse cursor, + then rip the two adjacent edges in the vert fan.*/ + if (em->bm->totvertsel == 1 && em->bm->totedgesel == 0 && em->bm->totfacesel == 0) { + /*find selected vert*/ + BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) + if (BM_TestHFlag(v, BM_SELECT)) + break; + + /*this should be impossible, but sanity checks are a good thing*/ + if (!v) + return OPERATOR_CANCELLED; + + /*find closest edge to mouse cursor*/ e2 = NULL; - i = 0; - BM_ITER(e, &eiter, em->bm, BM_EDGES_OF_VERT, v) { - if (BMINDEX_GET(e)) { + BM_ITER(e, &iter, em->bm, BM_EDGES_OF_VERT, v) { + d = mesh_rip_edgedist(ar, projectMat, e->v1->co, e->v2->co, event->mval); + if (d < dist) { + dist = d; e2 = e; - i++; } } - - if (i == 1 && e2->loop) { - l = BM_OtherFaceLoop(e2, e2->loop->f, v); - l = (BMLoop*)l->radial.next->data; - l = BM_OtherFaceLoop(l->e, l->f, v); - if (l) - BM_Select(em->bm, l->e, 1); + if (!e2) + return OPERATOR_CANCELLED; + + /*rip two adjacent edges*/ + if (BM_Edge_FaceCount(e2) == 1) { + l = e2->loop; + e = BM_OtherFaceLoop(e2, l->f, v); + + BMINDEX_SET(e, 1); + BM_SetHFlag(e, BM_SELECT); + } else if (BM_Edge_FaceCount(e2) == 2) { + l = e2->loop; + e = BM_OtherFaceLoop(e2, l->f, v); + BMINDEX_SET(e, 1); + BM_SetHFlag(e, BM_SELECT); + + l = e2->loop->radial.next->data; + e = BM_OtherFaceLoop(e2, l->f, v); + BMINDEX_SET(e, 1); + BM_SetHFlag(e, BM_SELECT); + } + } else { + /*expand edge selection*/ + BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { + e2 = NULL; + i = 0; + BM_ITER(e, &eiter, em->bm, BM_EDGES_OF_VERT, v) { + if (BMINDEX_GET(e)) { + e2 = e; + i++; + } + } + + if (i == 1 && e2->loop) { + l = BM_OtherFaceLoop(e2, e2->loop->f, v); + l = (BMLoop*)l->radial.next->data; + l = BM_OtherFaceLoop(l->e, l->f, v); + + if (l) + BM_Select(em->bm, l->e, 1); + } } } diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index a6c5e5beccf..bb69ab16a45 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -89,6 +89,34 @@ static int pupmenu() {return 0;} /* ***************** XXX **************** */ +/* copy the face flags, most importantly selection from the mesh to the final derived mesh, + * use in object mode when selecting faces (while painting) */ +void object_facesel_flush_dm(Object *ob) +{ + Mesh *me= get_mesh(ob); + DerivedMesh *dm= ob->derivedFinal; + MFace *faces, *mf, *mf_orig; + int *index_array = NULL; + int totface; + int i; + + + if(me==NULL || dm==NULL || !CustomData_has_layer( &dm->faceData, CD_ORIGINDEX)) + return; + + faces = dm->getTessFaceArray(dm); + totface = dm->getNumTessFaces(dm); + + index_array = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + + mf= faces; + + for (i= 0; i<totface; i++, mf++) { /* loop over derived mesh faces */ + mf_orig= me->mface + index_array[i]; + mf->flag= mf_orig->flag;; + } +} + /* returns 0 if not found, otherwise 1 */ int facesel_face_pick(View3D *v3d, Mesh *me, short *mval, unsigned int *index, short rect) { @@ -163,6 +191,7 @@ void reveal_tface(Scene *scene) mface++; } + object_facesel_flush_dm(OBACT); // XXX notifier! object_tface_flags_changed(OBACT, 0); } @@ -197,7 +226,8 @@ void hide_tface(Scene *scene) mface++; } - + + object_facesel_flush_dm(OBACT); // XXX notifier! object_tface_flags_changed(OBACT, 0); } @@ -237,7 +267,10 @@ void deselectall_tface(Scene *scene) sel= 0; while(a--) { if(mface->flag & ME_HIDE); - else if(mface->flag & ME_FACE_SEL) sel= 1; + else if(mface->flag & ME_FACE_SEL) { + sel= 1; + break; + } mface++; } @@ -252,6 +285,7 @@ void deselectall_tface(Scene *scene) mface++; } + object_facesel_flush_dm(OBACT); // XXX notifier! object_tface_flags_changed(OBACT, 0); } @@ -274,7 +308,8 @@ void selectswap_tface(Scene *scene) } mface++; } - + + object_facesel_flush_dm(OBACT); // XXX notifier! object_tface_flags_changed(OBACT, 0); } @@ -655,11 +690,11 @@ void face_select(Scene *scene, View3D *v3d) /* image window redraw */ - + object_facesel_flush_dm(OBACT); // XXX notifier! object_tface_flags_changed(OBACT, 1); } -void face_borderselect(Scene *scene, ARegion *ar) +void face_borderselect(Scene *scene, ScrArea *sa, ARegion *ar) { Mesh *me; MFace *mface; @@ -675,13 +710,15 @@ void face_borderselect(Scene *scene, ARegion *ar) // XXX val= get_border(&rect, 3); - /* why readbuffer here? shouldn't be necessary (maybe a flush or so) */ - glReadBuffer(GL_BACK); -#ifdef __APPLE__ - glReadBuffer(GL_AUX0); /* apple only */ -#endif - if(val) { + /* without this border select often fails */ +#if 0 /* XXX untested in 2.5 */ + if (v3d->flag & V3D_NEEDBACKBUFDRAW) { + check_backbuf(); + persp(PERSP_VIEW); + } +#endif + selar= MEM_callocN(me->totface+1, "selar"); sx= (rect.xmax-rect.xmin+1); @@ -722,6 +759,8 @@ void face_borderselect(Scene *scene, ARegion *ar) #ifdef __APPLE__ glReadBuffer(GL_BACK); #endif + + object_facesel_flush_dm(OBACT); } diff --git a/source/blender/editors/mesh/editmesh.c b/source/blender/editors/mesh/editmesh.c index d2fd5a309e1..e2bbb63f5c5 100644 --- a/source/blender/editors/mesh/editmesh.c +++ b/source/blender/editors/mesh/editmesh.c @@ -735,7 +735,6 @@ EditMesh *make_editMesh(Scene *scene, Object *ob) tot= actkey->totelem; } - /* make editverts */ CustomData_copy(&me->vdata, &em->vdata, CD_MASK_EDITMESH, CD_CALLOC, 0); mvert= me->mvert; @@ -745,10 +744,14 @@ EditMesh *make_editMesh(Scene *scene, Object *ob) co= mvert->co; + /* edit the shape key coordinate if available */ + if(actkey && a < actkey->totelem) + co= (float*)actkey->data + 3*a; + eve= addvertlist(em, co, NULL); evlist[a]= eve; - // face select sets selection in next loop + /* face select sets selection in next loop */ if(!paint_facesel_test(ob)) eve->f |= (mvert->flag & 1); @@ -931,6 +934,8 @@ void load_editMesh(Scene *scene, Object *ob, EditMesh *em) CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN, mface, me->totface); mesh_update_customdata_pointers(me); + em->mat_nr= ob->actcol-1; + /* the vertices, use ->tmp.l as counter */ eve= em->verts.first; a= 0; @@ -1241,6 +1246,7 @@ static EnumPropertyItem prop_separate_types[] = { /* return 1: success */ static int mesh_separate_selected(Scene *scene, Base *editbase) { +#if 0 EditMesh *em, *emnew; EditVert *eve, *v1; EditEdge *eed, *e1; @@ -1285,10 +1291,14 @@ static int mesh_separate_selected(Scene *scene, Base *editbase) ED_base_object_select(basenew, BA_DESELECT); /* 2 */ - basenew->object->data= menew= add_mesh(me->id.name); /* empty */ + basenew->object->data= menew= add_mesh(me->id.name+2); /* empty */ + assign_matarar(basenew->object, give_matarar(obedit), *give_totcolp(obedit)); /* new in 2.5 */ me->id.us--; emnew = make_editMesh(scene, basenew->object); //emnew= menew->edit_mesh; + CustomData_copy(&em->vdata, &emnew->vdata, CD_MASK_EDITMESH, CD_DEFAULT, 0); + CustomData_copy(&em->edata, &emnew->edata, CD_MASK_EDITMESH, CD_DEFAULT, 0); + CustomData_copy(&em->fdata, &emnew->fdata, CD_MASK_EDITMESH, CD_DEFAULT, 0); /* 3 */ /* SPLIT: first make duplicate */ @@ -1331,6 +1341,8 @@ static int mesh_separate_selected(Scene *scene, Base *editbase) /* 5 */ load_editMesh(scene, basenew->object, emnew); free_editMesh(emnew); + MEM_freeN(menew->edit_mesh); + menew->edit_mesh= NULL; /* hashedges are invalid now, make new! */ editMesh_set_hash(em); @@ -1341,11 +1353,13 @@ static int mesh_separate_selected(Scene *scene, Base *editbase) BKE_mesh_end_editmesh(me, em); return 1; +#endif } /* return 1: success */ static int mesh_separate_material(Scene *scene, Base *editbase) { +#if 0 Mesh *me= editbase->object->data; EditMesh *em= BKE_mesh_get_editmesh(me); unsigned char curr_mat; @@ -1364,6 +1378,7 @@ static int mesh_separate_material(Scene *scene, Base *editbase) BKE_mesh_end_editmesh(me, em); return 1; +#endif } /* return 1: success */ diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index b84ba39fc8e..e6baa6d9db8 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -71,6 +71,7 @@ #include "ED_transform.h" #include "ED_util.h" #include "ED_view3d.h" +#include "ED_object.h" #include "bmesh.h" @@ -1080,14 +1081,14 @@ static void make_prim(Object *obedit, int type, float mat[4][4], int tot, int se /* center vertices */ /* type PRIM_CONE can only have 1 one side filled * if the cone has no capping, dont add vtop */ - if((fill && type>1) || type == PRIM_CONE) { + if(type == PRIM_CONE || (fill && !ELEM(type, PRIM_PLANE, PRIM_CUBE))) { vec[0]= vec[1]= 0.0f; - vec[2]= -depth; + vec[2]= type==PRIM_CONE ? depth : -depth; Mat4MulVecfl(mat, vec); vdown= addvertlist(em, vec, NULL); if((ext || type==PRIM_CONE) && fill) { vec[0]= vec[1]= 0.0f; - vec[2]= depth; + vec[2]= type==PRIM_CONE ? -depth : depth; Mat4MulVecfl(mat,vec); vtop= addvertlist(em, vec, NULL); } @@ -1100,7 +1101,7 @@ static void make_prim(Object *obedit, int type, float mat[4][4], int tot, int se /* top and bottom face */ if(fill || type==PRIM_CONE) { - if(tot==4 && (type==0 || type==1)) { + if(tot==4 && ELEM(type, PRIM_PLANE, PRIM_CUBE)) { v3= v1->next->next; if(ext) v4= v2->next->next; @@ -1119,7 +1120,7 @@ static void make_prim(Object *obedit, int type, float mat[4][4], int tot, int se v4= v4->next; } } - if(type>1) { + if(!ELEM(type, PRIM_PLANE, PRIM_CUBE)) { addfacelist(em, vdown, v3, v1, 0, NULL, NULL); if(ext) addfacelist(em, vtop, v4, v2, 0, NULL, NULL); } @@ -1144,7 +1145,7 @@ static void make_prim(Object *obedit, int type, float mat[4][4], int tot, int se } addfacelist(em, v3, v1, v2, v4, NULL, NULL); } - else if(type==PRIM_CONE && fill) { + else if(fill && type==PRIM_CONE) { /* add the bottom flat area of the cone * if capping is disabled dont bother */ v3= v1; @@ -1160,7 +1161,7 @@ static void make_prim(Object *obedit, int type, float mat[4][4], int tot, int se /* simple selection flush OK, based on fact it's a single model */ EM_select_flush(em); /* flushes vertex -> edge -> face selection */ - if(type!=0 && type!=13) + if(type!=PRIM_PLANE && type!=PRIM_MONKEY) righthandfaces(em, 1); /* otherwise monkey has eyes in wrong direction */ BKE_mesh_end_editmesh(obedit->data, em); @@ -1203,20 +1204,41 @@ static float new_primitive_matrix(bContext *C, float primmat[][4]) /* ********* add primitive operators ************* */ -static int add_primitive_plane_exec(bContext *C, wmOperator *op) +static void make_prim_ext(bContext *C, int type, int tot, int seg, + int subdiv, float dia, float depth, int ext, int fill) { Object *obedit= CTX_data_edit_object(C); - float dia, mat[4][4]; - - dia= new_primitive_matrix(C, mat); - /* plane (diameter of 1.41 makes it unit size) */ - dia*= sqrt(2.0f); - - make_prim(obedit, PRIM_PLANE, mat, 4, 0, 0, dia, 0.0f, 0, 1); - + int newob; + float mat[4][4]; + + if(obedit==NULL || obedit->type!=OB_MESH) { + /* create editmode */ + ED_object_add_type(C, OB_MESH); + ED_object_enter_editmode(C, EM_DO_UNDO); + obedit= CTX_data_edit_object(C); + newob = 1; + } + else DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); + + dia *= new_primitive_matrix(C, mat); + + make_prim(obedit, type, mat, tot, seg, subdiv, dia, depth, ext, fill); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - + + + /* userdef */ + if (newob && (U.flag & USER_ADD_EDITMODE)==0) { + ED_object_exit_editmode(C, EM_FREEDATA); /* adding EM_DO_UNDO messes up operator redo */ + } + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); +} + +static int add_primitive_plane_exec(bContext *C, wmOperator *op) +{ + /* sqrt(2.0f) - plane (diameter of 1.41 makes it unit size) */ + make_prim_ext(C, PRIM_PLANE, 4, 0, 0, sqrt(2.0f), 0.0f, 0, 1); return OPERATOR_FINISHED; } @@ -1229,7 +1251,7 @@ void MESH_OT_primitive_plane_add(wmOperatorType *ot) /* api callbacks */ ot->exec= add_primitive_plane_exec; - ot->poll= ED_operator_editmesh; + ot->poll= ED_operator_scene_editable; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -1237,19 +1259,9 @@ void MESH_OT_primitive_plane_add(wmOperatorType *ot) static int add_primitive_cube_exec(bContext *C, wmOperator *op) { - Object *obedit= CTX_data_edit_object(C); - float dia, mat[4][4]; - - dia= new_primitive_matrix(C, mat); - /* plane (diameter of 1.41 makes it unit size) */ - dia*= sqrt(2.0f); - - make_prim(obedit, PRIM_CUBE, mat, 4, 0, 0, dia, 1.0f, 1, 1); - - DAG_id_flush_update(obedit->data, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - - return OPERATOR_FINISHED; + /* sqrt(2.0f) - plane (diameter of 1.41 makes it unit size) */ + make_prim_ext(C, PRIM_CUBE, 4, 0, 0, sqrt(2.0f), 1.0f, 1, 1); + return OPERATOR_FINISHED; } void MESH_OT_primitive_cube_add(wmOperatorType *ot) @@ -1261,7 +1273,7 @@ void MESH_OT_primitive_cube_add(wmOperatorType *ot) /* api callbacks */ ot->exec= add_primitive_cube_exec; - ot->poll= ED_operator_editmesh; + ot->poll= ED_operator_scene_editable; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -1269,18 +1281,10 @@ void MESH_OT_primitive_cube_add(wmOperatorType *ot) static int add_primitive_circle_exec(bContext *C, wmOperator *op) { - Object *obedit= CTX_data_edit_object(C); - float dia, mat[4][4]; - - dia= new_primitive_matrix(C, mat); - dia *= RNA_float_get(op->ptr,"radius"); - - make_prim(obedit, PRIM_CIRCLE, mat, RNA_int_get(op->ptr, "vertices"), 0, 0, dia, 0.0f, 0, - RNA_boolean_get(op->ptr, "fill")); - - DAG_id_flush_update(obedit->data, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - + make_prim_ext(C, PRIM_CIRCLE, RNA_int_get(op->ptr, "vertices"), 0, 0, + RNA_float_get(op->ptr,"radius"), 0.0f, 0, + RNA_boolean_get(op->ptr, "fill")); + return OPERATOR_FINISHED; } @@ -1293,32 +1297,24 @@ void MESH_OT_primitive_circle_add(wmOperatorType *ot) /* api callbacks */ ot->exec= add_primitive_circle_exec; - ot->poll= ED_operator_editmesh; + ot->poll= ED_operator_scene_editable; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* props */ RNA_def_int(ot->srna, "vertices", 32, INT_MIN, INT_MAX, "Vertices", "", 3, 500); - RNA_def_float(ot->srna, "radius", 1.0f, -FLT_MAX, FLT_MAX, "Radius", "", 0.001, 100.00); + RNA_def_float(ot->srna, "radius", 1.0f, 0.0, FLT_MAX, "Radius", "", 0.001, 100.00); RNA_def_boolean(ot->srna, "fill", 0, "Fill", ""); } static int add_primitive_cylinder_exec(bContext *C, wmOperator *op) { - Object *obedit= CTX_data_edit_object(C); - float dia, mat[4][4]; - - dia= new_primitive_matrix(C, mat); - dia *= RNA_float_get(op->ptr, "radius"); - - make_prim(obedit, PRIM_CYLINDER, mat, RNA_int_get(op->ptr, "vertices"), 0, 0, dia, - RNA_float_get(op->ptr, "depth"), 1, 1); - - DAG_id_flush_update(obedit->data, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - - return OPERATOR_FINISHED; + make_prim_ext(C, PRIM_CYLINDER, RNA_int_get(op->ptr, "vertices"), 0, 0, + RNA_float_get(op->ptr,"radius"), + RNA_float_get(op->ptr, "depth"), 1, 1); + + return OPERATOR_FINISHED; } void MESH_OT_primitive_cylinder_add(wmOperatorType *ot) @@ -1330,31 +1326,23 @@ void MESH_OT_primitive_cylinder_add(wmOperatorType *ot) /* api callbacks */ ot->exec= add_primitive_cylinder_exec; - ot->poll= ED_operator_editmesh; + ot->poll= ED_operator_scene_editable; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* props */ RNA_def_int(ot->srna, "vertices", 32, INT_MIN, INT_MAX, "Vertices", "", 2, 500); - RNA_def_float(ot->srna, "radius", 1.0f, -FLT_MAX, FLT_MAX, "Radius", "", 0.001, 100.00); - RNA_def_float(ot->srna, "depth", 1.0f, -FLT_MAX, FLT_MAX, "Depth", "", 0.001, 100.00); + RNA_def_float(ot->srna, "radius", 1.0f, 0.0, FLT_MAX, "Radius", "", 0.001, 100.00); + RNA_def_float(ot->srna, "depth", 1.0f, 0.0, FLT_MAX, "Depth", "", 0.001, 100.00); } static int add_primitive_tube_exec(bContext *C, wmOperator *op) { - Object *obedit= CTX_data_edit_object(C); - float dia, mat[4][4]; - - dia= new_primitive_matrix(C, mat); - dia *= RNA_float_get(op->ptr, "radius"); - - make_prim(obedit, PRIM_CYLINDER, mat, RNA_int_get(op->ptr, "vertices"), 0, 0, dia, - RNA_float_get(op->ptr, "depth"), 1, 0); - - DAG_id_flush_update(obedit->data, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - + make_prim_ext(C, PRIM_CYLINDER, RNA_int_get(op->ptr, "vertices"), 0, 0, + RNA_float_get(op->ptr,"radius"), + RNA_float_get(op->ptr, "depth"), 1, 0); + return OPERATOR_FINISHED; } @@ -1367,32 +1355,24 @@ void MESH_OT_primitive_tube_add(wmOperatorType *ot) /* api callbacks */ ot->exec= add_primitive_tube_exec; - ot->poll= ED_operator_editmesh; + ot->poll= ED_operator_scene_editable; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* props */ RNA_def_int(ot->srna, "vertices", 32, INT_MIN, INT_MAX, "Vertices", "", 2, 500); - RNA_def_float(ot->srna, "radius", 1.0f, -FLT_MAX, FLT_MAX, "Radius", "", 0.001, 100.00); - RNA_def_float(ot->srna, "depth", 1.0f, -FLT_MAX, FLT_MAX, "Depth", "", 0.001, 100.00); + RNA_def_float(ot->srna, "radius", 1.0f, 0.0, FLT_MAX, "Radius", "", 0.001, 100.00); + RNA_def_float(ot->srna, "depth", 1.0f, 0.0, FLT_MAX, "Depth", "", 0.001, 100.00); } static int add_primitive_cone_exec(bContext *C, wmOperator *op) { - Object *obedit= CTX_data_edit_object(C); - float dia, mat[4][4]; - - dia= new_primitive_matrix(C, mat); - dia *= RNA_float_get(op->ptr, "radius"); - - make_prim(obedit, PRIM_CONE, mat, RNA_int_get(op->ptr, "vertices"), 0, 0, dia, - RNA_float_get(op->ptr, "depth"), 0, RNA_boolean_get(op->ptr, "cap_end")); - - DAG_id_flush_update(obedit->data, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - - return OPERATOR_FINISHED; + make_prim_ext(C, PRIM_CONE, RNA_int_get(op->ptr, "vertices"), 0, 0, + RNA_float_get(op->ptr,"radius"), RNA_float_get(op->ptr, "depth"), + 0, RNA_boolean_get(op->ptr, "cap_end")); + + return OPERATOR_FINISHED; } void MESH_OT_primitive_cone_add(wmOperatorType *ot) @@ -1404,34 +1384,26 @@ void MESH_OT_primitive_cone_add(wmOperatorType *ot) /* api callbacks */ ot->exec= add_primitive_cone_exec; - ot->poll= ED_operator_editmesh; + ot->poll= ED_operator_scene_editable; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* props */ RNA_def_int(ot->srna, "vertices", 32, INT_MIN, INT_MAX, "Vertices", "", 2, 500); - RNA_def_float(ot->srna, "radius", 1.0f, -FLT_MAX, FLT_MAX, "Radius", "", 0.001, 100.00); - RNA_def_float(ot->srna, "depth", 1.0f, -FLT_MAX, FLT_MAX, "Depth", "", 0.001, 100.00); + RNA_def_float(ot->srna, "radius", 1.0f, 0.0, FLT_MAX, "Radius", "", 0.001, 100.00); + RNA_def_float(ot->srna, "depth", 1.0f, 0.0, FLT_MAX, "Depth", "", 0.001, 100.00); RNA_def_boolean(ot->srna, "cap_end", 0, "Cap End", ""); } static int add_primitive_grid_exec(bContext *C, wmOperator *op) { - Object *obedit= CTX_data_edit_object(C); - float dia, mat[4][4]; - - dia= new_primitive_matrix(C, mat); - dia*= RNA_float_get(op->ptr, "size"); - - make_prim(obedit, PRIM_GRID, mat, RNA_int_get(op->ptr, "x_subdivisions"), - RNA_int_get(op->ptr, "y_subdivisions"), 0, dia, 0.0f, 0, 1); - - DAG_id_flush_update(obedit->data, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - - return OPERATOR_FINISHED; + make_prim_ext(C, PRIM_GRID, RNA_int_get(op->ptr, "x_subdivisions"), + RNA_int_get(op->ptr, "y_subdivisions"), 0, + RNA_float_get(op->ptr,"size"), 0.0f, 0, 1); + + return OPERATOR_FINISHED; } void MESH_OT_primitive_grid_add(wmOperatorType *ot) @@ -1443,30 +1415,21 @@ void MESH_OT_primitive_grid_add(wmOperatorType *ot) /* api callbacks */ ot->exec= add_primitive_grid_exec; - ot->poll= ED_operator_editmesh; + ot->poll= ED_operator_scene_editable; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* props */ RNA_def_int(ot->srna, "x_subdivisions", 10, INT_MIN, INT_MAX, "X Subdivisions", "", 3, 1000); - RNA_def_int(ot->srna, "y_subdivisions", 10, INT_MIN, INT_MAX, "Y Subdivisons", "", 3, 1000); - RNA_def_float(ot->srna, "size", 1.0f, -FLT_MAX, FLT_MAX, "Size", "", 0.001, FLT_MAX); + RNA_def_int(ot->srna, "y_subdivisions", 10, INT_MIN, INT_MAX, "Y Subdivisions", "", 3, 1000); + RNA_def_float(ot->srna, "size", 1.0f, 0.0, FLT_MAX, "Size", "", 0.001, FLT_MAX); } static int add_primitive_monkey_exec(bContext *C, wmOperator *op) { - Object *obedit= CTX_data_edit_object(C); - float mat[4][4]; - - new_primitive_matrix(C, mat); - - make_prim(obedit, PRIM_MONKEY, mat, 0, 0, 2, 0.0f, 0.0f, 0, 0); - - DAG_id_flush_update(obedit->data, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - - return OPERATOR_FINISHED; + make_prim_ext(C, PRIM_MONKEY, 0, 0, 2, 0.0f, 0.0f, 0, 0); + return OPERATOR_FINISHED; } void MESH_OT_primitive_monkey_add(wmOperatorType *ot) @@ -1478,7 +1441,7 @@ void MESH_OT_primitive_monkey_add(wmOperatorType *ot) /* api callbacks */ ot->exec= add_primitive_monkey_exec; - ot->poll= ED_operator_editmesh; + ot->poll= ED_operator_scene_editable; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -1486,18 +1449,10 @@ void MESH_OT_primitive_monkey_add(wmOperatorType *ot) static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op) { - Object *obedit= CTX_data_edit_object(C); - float dia, mat[4][4]; - - dia= new_primitive_matrix(C, mat); - dia*= RNA_float_get(op->ptr, "size"); + make_prim_ext(C, PRIM_UVSPHERE, RNA_int_get(op->ptr, "rings"), + RNA_int_get(op->ptr, "segments"), 0, + RNA_float_get(op->ptr,"size"), 0.0f, 0, 0); - make_prim(obedit, PRIM_UVSPHERE, mat, RNA_int_get(op->ptr, "rings"), - RNA_int_get(op->ptr, "segments"), 0, dia, 0.0f, 0, 0); - - DAG_id_flush_update(obedit->data, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - return OPERATOR_FINISHED; } @@ -1510,7 +1465,7 @@ void MESH_OT_primitive_uv_sphere_add(wmOperatorType *ot) /* api callbacks */ ot->exec= add_primitive_uvsphere_exec; - ot->poll= ED_operator_editmesh; + ot->poll= ED_operator_scene_editable; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -1518,23 +1473,14 @@ void MESH_OT_primitive_uv_sphere_add(wmOperatorType *ot) /* props */ RNA_def_int(ot->srna, "segments", 32, INT_MIN, INT_MAX, "Segments", "", 3, 500); RNA_def_int(ot->srna, "rings", 24, INT_MIN, INT_MAX, "Rings", "", 3, 500); - RNA_def_float(ot->srna, "size", 1.0f, -FLT_MAX, FLT_MAX, "Size", "", 0.001, 100.00); + RNA_def_float(ot->srna, "size", 1.0f, 0.0, FLT_MAX, "Size", "", 0.001, 100.00); } static int add_primitive_icosphere_exec(bContext *C, wmOperator *op) { - Object *obedit= CTX_data_edit_object(C); - float dia, mat[4][4]; - - dia= new_primitive_matrix(C, mat); - dia*= RNA_float_get(op->ptr, "size"); - - make_prim(obedit, PRIM_ICOSPHERE, mat, 0, 0, - RNA_int_get(op->ptr, "subdivisions"), dia, 0.0f, 0, 0); - - DAG_id_flush_update(obedit->data, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - + make_prim_ext(C, PRIM_ICOSPHERE, 0, 0, RNA_int_get(op->ptr, "subdivisions"), + RNA_float_get(op->ptr,"size"), 0.0f, 0, 0); + return OPERATOR_FINISHED; } @@ -1547,7 +1493,7 @@ void MESH_OT_primitive_ico_sphere_add(wmOperatorType *ot) /* api callbacks */ ot->exec= add_primitive_icosphere_exec; - ot->poll= ED_operator_editmesh; + ot->poll= ED_operator_scene_editable; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c index b240896ec9c..a57d56ec1eb 100644 --- a/source/blender/editors/mesh/editmesh_mods.c +++ b/source/blender/editors/mesh/editmesh_mods.c @@ -1047,26 +1047,6 @@ static int loop_multiselect(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -#if 0 //moved to bmeshutils_mods.c -void MESH_OT_loop_multi_select(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Multi Select Loops"; - ot->description= "Select a loop of connected edges by connection type."; - ot->idname= "MESH_OT_loop_multi_select"; - - /* api callbacks */ - ot->exec= loop_multiselect; - ot->poll= ED_operator_editmesh; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - /* properties */ - RNA_def_boolean(ot->srna, "ring", 0, "Ring", ""); -} -#endif - /* ************************* */ /* ************************* */ @@ -1668,6 +1648,11 @@ void EM_toggle_select_all(EditMesh *em) /* exported for UV */ EM_set_flag_all(em, SELECT); } +void EM_select_all(EditMesh *em) +{ + EM_set_flag_all(em, SELECT); +} + void MESH_OT_bmesh_test(wmOperatorType *ot) { /* identifiers */ @@ -1851,7 +1836,7 @@ void MESH_OT_select_random(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* props */ - RNA_def_float_percentage(ot->srna, "percent", 0.5f, 0.0f, 1.0f, "Percent", "Percentage of vertices to select randomly.", 0.0001f, 1.0f); + RNA_def_float_percentage(ot->srna, "percent", 50.0f, 0.0f, 100.0f, "Percent", "Percentage of vertices to select randomly.", 0.0001f, 1.0f); } void EM_select_by_material(EditMesh *em, int index) diff --git a/source/blender/editors/mesh/loopcut.c b/source/blender/editors/mesh/loopcut.c index 686f0fd9348..9a2a953f643 100644 --- a/source/blender/editors/mesh/loopcut.c +++ b/source/blender/editors/mesh/loopcut.c @@ -51,6 +51,7 @@ #include "BKE_blender.h" #include "BKE_context.h" +#include "BKE_depsgraph.h" #include "BKE_scene.h" #include "BKE_utildefines.h" #include "BKE_mesh.h" @@ -132,7 +133,7 @@ static void edgering_sel(tringselOpData *lcd, int previewlines, int select) float (*edges)[2][3] = NULL; BLI_array_declare(edges); float co[2][3]; - int looking=1, i, j=0, tot=0; + int looking=1, i, tot=0; if (!startedge) return; @@ -246,28 +247,29 @@ static void edgering_sel(tringselOpData *lcd, int previewlines, int select) lcd->totedge = tot; } -static void ringsel_find_edge(tringselOpData *lcd, const bContext *C, ARegion *ar) +static void ringsel_find_edge(tringselOpData *lcd, const bContext *C, ARegion *ar, int cuts) { if (lcd->eed) - edgering_sel(lcd, 1, 0); + edgering_sel(lcd, cuts, 0); } static void ringsel_finish(bContext *C, wmOperator *op) { tringselOpData *lcd= op->customdata; + int cuts= RNA_int_get(op->ptr,"number_cuts"); if (lcd->eed) { - edgering_sel(lcd, 0, 1); + edgering_sel(lcd, cuts, 1); if (lcd->do_cut) { BMEditMesh *em = lcd->em; - BM_esubdivideflag(lcd->ob, em->bm, BM_SELECT, 0.0f, - 0.0f, 0, 1, SUBDIV_SELECT_LOOPCUT, + 0.0f, 0, cuts, SUBDIV_SELECT_LOOPCUT, SUBD_PATH, 0, 0); WM_event_add_notifier(C, NC_GEOM|ND_SELECT|ND_DATA, lcd->ob->data); DAG_id_flush_update(lcd->ob->data, OB_RECALC_DATA); } + WM_event_add_notifier(C, NC_GEOM|ND_DATA, lcd->ob->data); } } @@ -320,7 +322,6 @@ static int ringsel_cancel (bContext *C, wmOperator *op) static int ringsel_invoke (bContext *C, wmOperator *op, wmEvent *evt) { - ScrArea *sa = CTX_wm_area(C); tringselOpData *lcd; BMEdge *edge; int dist = 75; @@ -331,7 +332,7 @@ static int ringsel_invoke (bContext *C, wmOperator *op, wmEvent *evt) return OPERATOR_CANCELLED; /* add a modal handler for this operator - handles loop selection */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); lcd = op->customdata; lcd->vc.mval[0] = evt->mval[0]; @@ -340,7 +341,7 @@ static int ringsel_invoke (bContext *C, wmOperator *op, wmEvent *evt) edge = EDBM_findnearestedge(&lcd->vc, &dist); if (edge != lcd->eed) { lcd->eed = edge; - ringsel_find_edge(lcd, C, lcd->ar); + ringsel_find_edge(lcd, C, lcd->ar, 1); } return OPERATOR_RUNNING_MODAL; @@ -349,7 +350,6 @@ static int ringsel_invoke (bContext *C, wmOperator *op, wmEvent *evt) static int ringcut_invoke (bContext *C, wmOperator *op, wmEvent *evt) { - ScrArea *sa = CTX_wm_area(C); tringselOpData *lcd; BMEdge *edge; int dist = 75; @@ -360,7 +360,7 @@ static int ringcut_invoke (bContext *C, wmOperator *op, wmEvent *evt) return OPERATOR_CANCELLED; /* add a modal handler for this operator - handles loop selection */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); lcd = op->customdata; lcd->vc.mval[0] = evt->mval[0]; @@ -369,7 +369,7 @@ static int ringcut_invoke (bContext *C, wmOperator *op, wmEvent *evt) edge = EDBM_findnearestedge(&lcd->vc, &dist); if (edge != lcd->eed) { lcd->eed = edge; - ringsel_find_edge(lcd, C, lcd->ar); + ringsel_find_edge(lcd, C, lcd->ar, 1); } return OPERATOR_RUNNING_MODAL; @@ -377,23 +377,49 @@ static int ringcut_invoke (bContext *C, wmOperator *op, wmEvent *evt) static int ringsel_modal (bContext *C, wmOperator *op, wmEvent *event) { + int cuts= RNA_int_get(op->ptr,"number_cuts"); tringselOpData *lcd= op->customdata; view3d_operator_needs_opengl(C); + switch (event->type) { - case RIGHTMOUSE: case LEFTMOUSE: /* confirm */ // XXX hardcoded - if (event->val == 0) { + if (event->val == KM_RELEASE) { /* finish */ ED_region_tag_redraw(lcd->ar); - + ringsel_finish(C, op); ringsel_exit(C, op); return OPERATOR_FINISHED; } - + + ED_region_tag_redraw(lcd->ar); + break; + case RIGHTMOUSE: /* abort */ // XXX hardcoded + case ESCKEY: + if (event->val == KM_RELEASE) { + /* cancel */ + ED_region_tag_redraw(lcd->ar); + + return ringsel_cancel(C, op); + } + + ED_region_tag_redraw(lcd->ar); + break; + case WHEELUPMOUSE: /* change number of cuts */ + cuts++; + RNA_int_set(op->ptr,"number_cuts",cuts); + ringsel_find_edge(lcd, C, lcd->ar, cuts); + + ED_region_tag_redraw(lcd->ar); + break; + case WHEELDOWNMOUSE: /* change number of cuts */ + cuts=MAX2(cuts-1,1); + RNA_int_set(op->ptr,"number_cuts",cuts); + ringsel_find_edge(lcd, C, lcd->ar,cuts); + ED_region_tag_redraw(lcd->ar); break; case MOUSEMOVE: { /* mouse moved somewhere to select another loop */ @@ -406,12 +432,12 @@ static int ringsel_modal (bContext *C, wmOperator *op, wmEvent *event) if (edge != lcd->eed) { lcd->eed = edge; - ringsel_find_edge(lcd, C, lcd->ar); + ringsel_find_edge(lcd, C, lcd->ar, cuts); } ED_region_tag_redraw(lcd->ar); break; - } + } } /* keep going until the user confirms */ @@ -452,4 +478,7 @@ void MESH_OT_loopcut (wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; + + /* properties */ + RNA_def_int(ot->srna, "number_cuts", 1, 1, 10, "Number of Cuts", "", 1, INT_MAX); } diff --git a/source/blender/editors/mesh/mesh_layers.c b/source/blender/editors/mesh/mesh_data.c index be476b07a3f..848930e156b 100644 --- a/source/blender/editors/mesh/mesh_layers.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -26,12 +26,14 @@ * ***** END GPL LICENSE BLOCK ***** */ -#include <stdlib.h> #include <math.h> +#include <stdlib.h> +#include <string.h> #include "MEM_guardedalloc.h" #include "DNA_customdata_types.h" +#include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" @@ -43,10 +45,14 @@ #include "BKE_depsgraph.h" #include "BKE_displist.h" #include "BKE_global.h" +#include "BKE_material.h" #include "BKE_mesh.h" +#include "BKE_report.h" #include "BKE_tessmesh.h" +#include "BLI_arithb.h" #include "BLI_editVert.h" +#include "BLI_edgehash.h" #include "RNA_access.h" #include "RNA_define.h" @@ -59,23 +65,20 @@ #include "ED_view3d.h" #include "mesh_intern.h" -#include "bmesh.h" -static void delete_customdata_layer(bContext *C, Object *ob, CustomDataLayer *layer, int loop) +static void delete_customdata_layer(bContext *C, Object *ob, CustomDataLayer *layer) { - CustomData *data; Mesh *me = ob->data; + CustomData *data= (me->edit_btmesh)? &me->edit_btmesh->bm->pdata: &me->pdata; void *actlayerdata, *rndlayerdata, *clonelayerdata, *masklayerdata, *layerdata=layer->data; int type= layer->type; - int index; - int i, actindex, rndindex, cloneindex, maskindex; + int index= CustomData_get_layer_index(data, type); + int i, actindex, rndindex, cloneindex, maskindex, tot = me->totpoly; - if (loop) + if (layer->type == CD_MLOOPCOL) { data = (me->edit_btmesh)? &me->edit_btmesh->bm->ldata: &me->ldata; - else - data = (me->edit_btmesh)? &me->edit_btmesh->bm->pdata: &me->pdata; - - index = CustomData_get_layer_index(data, type); + tot = me->totloop; + } /* ok, deleting a non-active layer needs to preserve the active layer indices. to do this, we store a pointer to the .data member of both layer and the active layer, @@ -94,7 +97,7 @@ static void delete_customdata_layer(bContext *C, Object *ob, CustomDataLayer *la BM_free_data_layer(me->edit_btmesh->bm, data, type); } else { - CustomData_free_layer_active(data, type, loop ? me->totloop : me->totpoly); + CustomData_free_layer_active(data, type, tot); mesh_update_customdata_pointers(me); } @@ -157,67 +160,140 @@ static void delete_customdata_layer(bContext *C, Object *ob, CustomDataLayer *la /* set index */ CustomData_set_layer_mask(data, type, maskindex); } +} + +int ED_mesh_uv_texture_add(bContext *C, Scene *scene, Object *ob, Mesh *me) +{ + BMEditMesh *em; + int layernum; + + if(me->edit_btmesh) { + em= me->edit_btmesh; + + layernum= CustomData_number_of_layers(&em->bm->pdata, CD_MTEXPOLY); + if(layernum >= MAX_MTFACE) + return OPERATOR_CANCELLED; + + BM_add_data_layer(em->bm, &em->bm->pdata, MAX_MTFACE); + CustomData_set_layer_active(&em->bm->pdata, MAX_MTFACE, layernum); + } + else { + layernum= CustomData_number_of_layers(&me->pdata, MAX_MTFACE); + if(layernum >= MAX_MTFACE) + return OPERATOR_CANCELLED; - if (!me->edit_btmesh) { - /*recalc mesh tesselation*/ - me->totface = mesh_recalcTesselation(&me->fdata, &me->ldata, - &me->pdata, me->mvert, me->totface, me->totloop, me->totpoly); + if(me->mtface) + CustomData_add_layer(&me->pdata, MAX_MTFACE, CD_DUPLICATE, me->mtpoly, me->totpoly); + else + CustomData_add_layer(&me->pdata, MAX_MTFACE, CD_DEFAULT, NULL, me->totpoly); + CustomData_set_layer_active(&me->pdata, MAX_MTFACE, layernum); mesh_update_customdata_pointers(me); } -} -/*********************** UV texture operators ************************/ + DAG_id_flush_update(&me->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, me); -static int layers_poll(bContext *C) + return 1; +} + +int ED_mesh_uv_texture_remove(bContext *C, Object *ob, Mesh *me) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - ID *data= (ob)? ob->data: NULL; - return (ob && !ob->id.lib && ob->type==OB_MESH && data && !data->lib); + CustomDataLayer *cdl; + int index; + + index= CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY); + cdl= (index == -1)? NULL: &me->pdata.layers[index]; + + if(!cdl) + return 0; + + delete_customdata_layer(C, ob, cdl); + DAG_id_flush_update(&me->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, me); + + return 1; } -static int uv_texture_add_exec(bContext *C, wmOperator *op) +int ED_mesh_color_add(bContext *C, Scene *scene, Object *ob, Mesh *me) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - Mesh *me= ob->data; BMEditMesh *em; + MLoopCol *mcol; int layernum; if(me->edit_btmesh) { em= me->edit_btmesh; - layernum= CustomData_number_of_layers(&em->bm->pdata, CD_MTEXPOLY); - if(layernum >= MAX_MTFACE) - return OPERATOR_CANCELLED; + layernum= CustomData_number_of_layers(&em->bm->ldata, CD_MLOOPCOL); + if(layernum >= MAX_MCOL) + return 0; - BM_add_data_layer(em->bm, &em->bm->pdata, CD_MTEXPOLY); - BM_add_data_layer(em->bm, &em->bm->ldata, CD_MLOOPUV); - CustomData_set_layer_active(&em->bm->pdata, CD_MTEXPOLY, layernum); + BM_add_data_layer(em->bm, &em->bm->pdata, CD_MLOOPCOL); + CustomData_set_layer_active(&em->bm->ldata, CD_MLOOPCOL, layernum); } else { - layernum= CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY); - if(layernum >= MAX_MTFACE) - return OPERATOR_CANCELLED; + layernum= CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL); + if(layernum >= CD_MLOOPCOL) + return 0; - if (me->mtpoly) { - CustomData_add_layer(&me->pdata, CD_MTEXPOLY, CD_DUPLICATE, me->mtpoly, me->totpoly); - CustomData_add_layer(&me->ldata, CD_MLOOPUV, CD_DUPLICATE, me->mloopuv, me->totloop); - } else { - CustomData_add_layer(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly); - CustomData_add_layer(&me->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, me->totloop); - } - - CustomData_set_layer_active(&me->pdata, CD_MTEXPOLY, layernum); + mcol= me->mloopcol; + + if(me->mloopcol) + CustomData_add_layer(&me->ldata, CD_MLOOPCOL, CD_DUPLICATE, me->mloopcol, me->totloop); + else + CustomData_add_layer(&me->ldata, CD_MLOOPCOL, CD_DEFAULT, NULL, me->totloop); - /*recalc mesh tesselation*/ - me->totface = mesh_recalcTesselation(&me->fdata, &me->ldata, - &me->pdata, me->mvert, me->totface, me->totloop, me->totpoly); + CustomData_set_layer_active(&me->ldata, CD_MLOOPCOL, layernum); mesh_update_customdata_pointers(me); + + /*BMESH_TODO + if(!mcol) + shadeMeshMCol(scene, ob, me); + */ } DAG_id_flush_update(&me->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM|ND_DATA, me); + return 1; +} + +int ED_mesh_color_remove(bContext *C, Object *ob, Mesh *me) +{ + CustomDataLayer *cdl; + int index; + + index= CustomData_get_active_layer_index(&me->pdata, CD_MLOOPCOL); + cdl= (index == -1)? NULL: &me->pdata.layers[index]; + + if(!cdl) + return 0; + + delete_customdata_layer(C, ob, cdl); + DAG_id_flush_update(&me->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, me); + + return 1; +} + +/*********************** UV texture operators ************************/ + +static int layers_poll(bContext *C) +{ + Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + ID *data= (ob)? ob->data: NULL; + return (ob && !ob->id.lib && ob->type==OB_MESH && data && !data->lib); +} + +static int uv_texture_add_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Mesh *me= ob->data; + + if(!ED_mesh_uv_texture_add(C, scene, ob, me)) + return OPERATOR_CANCELLED; + return OPERATOR_FINISHED; } @@ -240,24 +316,10 @@ static int uv_texture_remove_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; Mesh *me= ob->data; - CustomDataLayer *cdl, *cdl2; - int index; - - index= CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY); - cdl= (index == -1)? NULL: &me->pdata.layers[index]; - - index= CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV); - cdl2= (index == -1)? NULL: &me->ldata.layers[index]; - if(!cdl) + if(!ED_mesh_uv_texture_remove(C, ob, me)) return OPERATOR_CANCELLED; - delete_customdata_layer(C, ob, cdl, 0); - delete_customdata_layer(C, ob, cdl2, 1); - - DAG_id_flush_update(&me->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, me); - return OPERATOR_FINISHED; } @@ -283,46 +345,9 @@ static int vertex_color_add_exec(bContext *C, wmOperator *op) Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; Mesh *me= ob->data; - BMEditMesh *em; - MLoopCol *mcol; - int layernum; - - if(me->edit_btmesh) { - em= me->edit_btmesh; - - layernum= CustomData_number_of_layers(&em->bm->ldata, CD_MLOOPCOL); - if(layernum >= MAX_MCOL) - return OPERATOR_CANCELLED; - - BM_add_data_layer(em->bm, &em->bm->ldata, CD_MLOOPCOL); - CustomData_set_layer_active(&em->bm->ldata, CD_MLOOPCOL, layernum); - } - else { - layernum= CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL); - if(layernum >= MAX_MCOL) - return OPERATOR_CANCELLED; - - mcol= me->mloopcol; - - if(me->mloopcol) - CustomData_add_layer(&me->ldata, CD_MLOOPCOL, CD_DUPLICATE, me->mloopcol, me->totloop); - else - CustomData_add_layer(&me->ldata, CD_MLOOPCOL, CD_DEFAULT, NULL, me->totloop); - - CustomData_set_layer_active(&me->ldata, CD_MLOOPCOL, layernum); - - /*recalc mesh tesselation*/ - me->totface = mesh_recalcTesselation(&me->fdata, &me->ldata, - &me->pdata, me->mvert, me->totface, me->totloop, me->totpoly); - - mesh_update_customdata_pointers(me); - - //if(!mcol) - // shadeMeshMCol(scene, ob, me); - } - DAG_id_flush_update(&me->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, me); + if(!ED_mesh_color_add(C, scene, ob, me)) + return OPERATOR_CANCELLED; return OPERATOR_FINISHED; } @@ -346,20 +371,10 @@ static int vertex_color_remove_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; Mesh *me= ob->data; - CustomDataLayer *cdl; - int index; - - index= CustomData_get_active_layer_index(&me->ldata, CD_MLOOPCOL); - cdl= (index == -1)? NULL: &me->ldata.layers[index]; - if(!cdl) + if(!ED_mesh_color_remove(C, ob, me)) return OPERATOR_CANCELLED; - delete_customdata_layer(C, ob, cdl, 1); - - DAG_id_flush_update(&me->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, me); - return OPERATOR_FINISHED; } @@ -443,3 +458,212 @@ void MESH_OT_sticky_remove(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } +/************************** Add Geometry Layers *************************/ + +static void mesh_calc_edges(Mesh *mesh) +{ + CustomData edata; + EdgeHashIterator *ehi; + MFace *mf = mesh->mface; + MEdge *med; + EdgeHash *eh = BLI_edgehash_new(); + int i, *index, totedge, totface = mesh->totface; + + for (i = 0; i < totface; i++, mf++) { + if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2)) + BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL); + if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3)) + BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL); + + if (mf->v4) { + if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4)) + BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL); + if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1)) + BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL); + } else { + if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1)) + BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL); + } + } + + totedge = BLI_edgehash_size(eh); + + /* write new edges into a temporary CustomData */ + memset(&edata, 0, sizeof(edata)); + CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge); + + ehi = BLI_edgehashIterator_new(eh); + med = CustomData_get_layer(&edata, CD_MEDGE); + for(i = 0; !BLI_edgehashIterator_isDone(ehi); + BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) { + BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2); + + med->flag = ME_EDGEDRAW|ME_EDGERENDER; + } + BLI_edgehashIterator_free(ehi); + + /* free old CustomData and assign new one */ + CustomData_free(&mesh->edata, mesh->totedge); + mesh->edata = edata; + mesh->totedge = totedge; + + mesh->medge = CustomData_get_layer(&mesh->edata, CD_MEDGE); + + BLI_edgehash_free(eh, NULL); +} + +void ED_mesh_update(Mesh *mesh, bContext *C, int calc_edges) +{ + if(calc_edges || (mesh->totface && mesh->totedge == 0)) + mesh_calc_edges(mesh); + + mesh_calc_normals(mesh->mvert, mesh->totvert, mesh->mface, mesh->totface, NULL); + + DAG_id_flush_update(&mesh->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, mesh); +} + +static void mesh_add_verts(Mesh *mesh, int len) +{ + CustomData vdata; + MVert *mvert; + int i, totvert; + + if(len == 0) + return; + + totvert= mesh->totvert + len; + CustomData_copy(&mesh->vdata, &vdata, CD_MASK_MESH, CD_DEFAULT, totvert); + CustomData_copy_data(&mesh->vdata, &vdata, 0, 0, mesh->totvert); + + if(!CustomData_has_layer(&vdata, CD_MVERT)) + CustomData_add_layer(&vdata, CD_MVERT, CD_CALLOC, NULL, totvert); + + CustomData_free(&mesh->vdata, mesh->totvert); + mesh->vdata= vdata; + mesh_update_customdata_pointers(mesh); + + /* scan the input list and insert the new vertices */ + + mvert= &mesh->mvert[mesh->totvert]; + for(i=0; i<len; i++, mvert++) + mvert->flag |= SELECT; + + /* set final vertex list size */ + mesh->totvert= totvert; +} + +void ED_mesh_transform(Mesh *me, float *mat) +{ + int i; + MVert *mvert= me->mvert; + + for(i= 0; i < me->totvert; i++, mvert++) + Mat4MulVecfl((float (*)[4])mat, mvert->co); + + mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); +} + +static void mesh_add_edges(Mesh *mesh, int len) +{ + CustomData edata; + MEdge *medge; + int i, totedge; + + if(len == 0) + return; + + totedge= mesh->totedge+len; + + /* update customdata */ + CustomData_copy(&mesh->edata, &edata, CD_MASK_MESH, CD_DEFAULT, totedge); + CustomData_copy_data(&mesh->edata, &edata, 0, 0, mesh->totedge); + + if(!CustomData_has_layer(&edata, CD_MEDGE)) + CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge); + + CustomData_free(&mesh->edata, mesh->totedge); + mesh->edata= edata; + mesh_update_customdata_pointers(mesh); + + /* set default flags */ + medge= &mesh->medge[mesh->totedge]; + for(i=0; i<len; i++, medge++) + medge->flag= ME_EDGEDRAW|ME_EDGERENDER|SELECT; + + mesh->totedge= totedge; +} + +static void mesh_add_faces(Mesh *mesh, int len) +{ + CustomData fdata; + MFace *mface; + int i, totface; + + if(len == 0) + return; + + totface= mesh->totface + len; /* new face count */ + + /* update customdata */ + CustomData_copy(&mesh->fdata, &fdata, CD_MASK_MESH, CD_DEFAULT, totface); + CustomData_copy_data(&mesh->fdata, &fdata, 0, 0, mesh->totface); + + if(!CustomData_has_layer(&fdata, CD_MFACE)) + CustomData_add_layer(&fdata, CD_MFACE, CD_CALLOC, NULL, totface); + + CustomData_free(&mesh->fdata, mesh->totface); + mesh->fdata= fdata; + mesh_update_customdata_pointers(mesh); + + /* set default flags */ + mface= &mesh->mface[mesh->totface]; + for(i=0; i<len; i++, mface++) + mface->flag= SELECT; + + mesh->totface= totface; +} + +void ED_mesh_geometry_add(Mesh *mesh, ReportList *reports, int verts, int edges, int faces) +{ + if(mesh->edit_btmesh) { + BKE_report(reports, RPT_ERROR, "Can't add geometry in edit mode."); + return; + } + + if(verts) + mesh_add_verts(mesh, verts); + if(edges) + mesh_add_edges(mesh, edges); + if(faces) + mesh_add_faces(mesh, faces); +} + +void ED_mesh_calc_normals(Mesh *me) +{ + mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); +} + +void ED_mesh_material_add(Mesh *me, Material *ma) +{ + int i; + int totcol = me->totcol + 1; + Material **mat; + + /* don't add if mesh already has it */ + for(i = 0; i < me->totcol; i++) + if(me->mat[i] == ma) + return; + + mat= MEM_callocN(sizeof(void*)*totcol, "newmatar"); + + if(me->totcol) memcpy(mat, me->mat, sizeof(void*) * me->totcol); + if(me->mat) MEM_freeN(me->mat); + + me->mat = mat; + me->mat[me->totcol++] = ma; + ma->id.us++; + + test_object_materials((ID*)me); +} + diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index 1dce47a7419..4a1532af3b0 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -110,12 +110,6 @@ extern struct EditEdge *addedgelist(EditMesh *em, struct EditVert *v1, struct Ed extern struct EditFace *addfacelist(EditMesh *em, struct EditVert *v1, struct EditVert *v2, struct EditVert *v3, struct EditVert *v4, struct EditFace *example, struct EditFace *exampleEdges); extern struct EditEdge *findedgelist(EditMesh *em, struct EditVert *v1, struct EditVert *v2); -EditVert *editedge_getOtherVert(EditEdge *eed, EditVert *eve); -EditVert *editedge_getSharedVert(EditEdge *eed, EditEdge *eed2); -int editedge_containsVert(struct EditEdge *eed, struct EditVert *eve); -int editface_containsVert(struct EditFace *efa, struct EditVert *eve); -int editface_containsEdge(struct EditFace *efa, struct EditEdge *eed); - void em_setup_viewcontext(struct bContext *C, struct ViewContext *vc); void MESH_OT_separate(struct wmOperatorType *ot); @@ -225,7 +219,7 @@ void MESH_OT_vertices_smooth(struct wmOperatorType *ot); void MESH_OT_flip_normals(struct wmOperatorType *ot); extern EditEdge *findnearestedge(struct ViewContext *vc, int *dist); -extern void EM_automerge(int update); +extern void EM_automerge(Scene *scene, Object *obedit, int update); void editmesh_select_by_material(EditMesh *em, int index); void righthandfaces(EditMesh *em, int select); /* makes faces righthand turning */ void EM_select_more(EditMesh *em); diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index e75781aab20..7b2522ac3d2 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -55,6 +55,7 @@ #include "WM_types.h" #include "ED_mesh.h" +#include "ED_object.h" #include "ED_screen.h" #include "ED_transform.h" #include "ED_view3d.h" @@ -63,186 +64,10 @@ #include "mesh_intern.h" -/******************************** menus *************************************/ - -static int vertex_specials_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - uiPopupMenu *pup; - uiLayout *layout; - - pup= uiPupMenuBegin(C, "Vertex Specials", 0); - layout= uiPupMenuLayout(pup); - uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN); - - uiItemO(layout, "Remove Doubles", 0, "MESH_OT_remove_doubles"); - uiItemO(layout, "Merge...", 0, "MESH_OT_merge"); - uiItemO(layout, "Smooth", 0, "MESH_OT_vertices_smooth"); - uiItemO(layout, "Select Vertex Path", 0, "MESH_OT_select_vertex_path"); - uiItemO(layout, "BMesh Test Operator", 0, "MESH_OT_bm_test"); - //uiItemO(layout, "Blend From Shape", 0, "MESH_OT_blend_from_shape"); - //uiItemO(layout, "Propagate to All Shapes", 0, "MESH_OT_shape_propagate_to_all"); - - uiPupMenuEnd(C, pup); - - return OPERATOR_CANCELLED; -} - -static void MESH_OT_vertex_specials(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Vertex Specials"; - //ot->description= "Perform special vertex operations."; - ot->idname= "MESH_OT_vertex_specials"; - - /* api callbacks */ - ot->invoke= vertex_specials_invoke; - ot->poll= ED_operator_editmesh; -} - -static int edge_specials_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - uiPopupMenu *pup; - uiLayout *layout; - - pup= uiPupMenuBegin(C, "Edge Specials", 0); - layout= uiPupMenuLayout(pup); - uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN); - - uiItemO(layout, "Mark Seam", 0, "MESH_OT_mark_seam"); - uiItemBooleanO(layout, "Clear Seam", 0, "MESH_OT_mark_seam", "clear", 1); - uiItemEnumO(layout, "Rotate Edge CW", 0, "MESH_OT_edge_rotate", "direction", 1); - uiItemEnumO(layout, "Rotate Edge CCW", 0, "MESH_OT_edge_rotate", "direction", 2); - //uiItemO(layout, "Loopcut", 0, "MESH_OT_loop_cut"); // CutEdgeloop(em, 1); - //uiItemO(layout, "Edge Slide", 0, "MESH_OT_edge_slide"); // EdgeSlide(em, 0,0.0); - uiItemO(layout, "Edge Loop", 0, "MESH_OT_loop_multi_select"); - uiItemBooleanO(layout, "Edge Ring", 0, "MESH_OT_loop_multi_select", "ring", 1); - uiItemO(layout, NULL, 0, "MESH_OT_loop_to_region"); - uiItemO(layout, NULL, 0, "MESH_OT_region_to_loop"); - uiItemO(layout, "Mark Sharp", 0, "MESH_OT_mark_sharp"); - uiItemBooleanO(layout, "Clear Sharp", 0, "MESH_OT_mark_sharp", "clear", 1); - - uiPupMenuEnd(C, pup); - - return OPERATOR_CANCELLED; -} - -static void MESH_OT_edge_specials(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Edge Specials"; - //ot->description= "Perform special edge operations."; - ot->idname= "MESH_OT_edge_specials"; - - /* api callbacks */ - ot->invoke= edge_specials_invoke; - ot->poll= ED_operator_editmesh; -} - -static int face_specials_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - uiPopupMenu *pup; - uiLayout *layout; - - pup= uiPupMenuBegin(C, "Face Specials", 0); - layout= uiPupMenuLayout(pup); - uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN); - - uiItemO(layout, NULL, 0, "MESH_OT_flip_normals"); - // uiItemO(layout, "Bevel", 0, "MESH_OT_bevel"); // bevelmenu(em) - uiItemO(layout, NULL, 0, "MESH_OT_faces_shade_smooth"); - uiItemO(layout, NULL, 0, "MESH_OT_faces_shade_flat"); - uiItemO(layout, NULL, 0, "MESH_OT_quads_convert_to_tris"); - uiItemO(layout, NULL, 0, "MESH_OT_tris_convert_to_quads"); - uiItemO(layout, NULL, 0, "MESH_OT_edge_flip"); - - uiItemS(layout); - - uiItemO(layout, NULL, 0, "MESH_OT_fill"); - uiItemO(layout, NULL, 0, "MESH_OT_beauty_fill"); - - uiItemS(layout); - - // uiItemO(layout, NULL, 0, "MESH_OT_face_mode"); // mesh_set_face_flags(em, 1); - // uiItemBooleanO(layout, NULL, 0, "MESH_OT_face_mode", "clear", 1); // mesh_set_face_flags(em, 0); - // - // uiItemS(layout); - - uiItemMenuEnumO(layout, NULL, 0, "MESH_OT_uvs_rotate", "direction"); - //uiItemMenuEnumO(layout, NULL, 0, "MESH_OT_uvs_mirror", "axis"); - uiItemO(layout, NULL, 0, "MESH_OT_uvs_reverse"); - uiItemMenuEnumO(layout, NULL, 0, "MESH_OT_colors_rotate", "direction"); - //uiItemMenuEnumO(layout, NULL, 0, "MESH_OT_colors_mirror", "axis"); - uiItemO(layout, NULL, 0, "MESH_OT_colors_reverse"); - - uiPupMenuEnd(C, pup); - - return OPERATOR_CANCELLED; -} - -static void MESH_OT_face_specials(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Face Specials"; - //ot->description= "Perform special face operations."; - ot->idname= "MESH_OT_face_specials"; - - /* api callbacks */ - ot->invoke= face_specials_invoke; - ot->poll= ED_operator_editmesh; -} - -static int specials_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - uiPopupMenu *pup; - uiLayout *layout; - - pup= uiPupMenuBegin(C, "Specials", 0); - layout= uiPupMenuLayout(pup); - uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN); - - uiItemO(layout, "Subdivide", 0, "MESH_OT_subdivide"); - uiItemFloatO(layout, "Subdivide Smooth", 0, "MESH_OT_subdivide", "smoothness", 1.0f); - uiItemO(layout, "Merge...", 0, "MESH_OT_merge"); - uiItemO(layout, "Remove Doubles", 0, "MESH_OT_remove_doubles"); - uiItemO(layout, "Hide", 0, "MESH_OT_hide"); - uiItemO(layout, "Reveal", 0, "MESH_OT_reveal"); - uiItemO(layout, "Pin", 0, "MESH_OT_pin"); - uiItemO(layout, "Unpin", 0, "MESH_OT_unpin"); - uiItemO(layout, "Select Inverse", 0, "MESH_OT_select_inverse"); - uiItemO(layout, NULL, 0, "MESH_OT_flip_normals"); - uiItemO(layout, "Smooth", 0, "MESH_OT_vertices_smooth"); - // uiItemO(layout, "Bevel", 0, "MESH_OT_bevel"); // bevelmenu(em) - uiItemO(layout, NULL, 0, "MESH_OT_faces_shade_smooth"); - uiItemO(layout, NULL, 0, "MESH_OT_faces_shade_flat"); - //uiItemO(layout, "Blend From Shape", 0, "MESH_OT_blend_from_shape"); - //uiItemO(layout, "Propagate to All Shapes", 0, "MESH_OT_shape_propagate_to_all"); - uiItemO(layout, "Select Vertex Path", 0, "MESH_OT_select_vertex_path"); - - uiPupMenuEnd(C, pup); - - return OPERATOR_CANCELLED; -} - -static void MESH_OT_specials(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Specials"; - //ot->description= "Perform special vertice, edge or face operations."; - ot->idname= "MESH_OT_specials"; - - /* api callbacks */ - ot->invoke= specials_invoke; - ot->poll= ED_operator_editmesh; -} - /**************************** registration **********************************/ void ED_operatortypes_mesh(void) { - wmOperatorType *ot; - wmOperatorTypeMacro *otm; - static int constraint_axis[3] = {0, 0, 1}; - WM_operatortype_append(MESH_OT_select_all_toggle); WM_operatortype_append(MESH_OT_select_more); WM_operatortype_append(MESH_OT_select_less); @@ -325,11 +150,6 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_vertex_color_remove); WM_operatortype_append(MESH_OT_sticky_add); WM_operatortype_append(MESH_OT_sticky_remove); - - WM_operatortype_append(MESH_OT_vertex_specials); - WM_operatortype_append(MESH_OT_edge_specials); - WM_operatortype_append(MESH_OT_face_specials); - WM_operatortype_append(MESH_OT_specials); WM_operatortype_append(MESH_OT_vert_connect); WM_operatortype_append(MESH_OT_edge_split); @@ -342,8 +162,12 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_edgering_select); WM_operatortype_append(MESH_OT_loopcut); +} - /* macros */ +void ED_operatormacros_mesh(void) +{ + wmOperatorType *ot; + wmOperatorTypeMacro *otmacro; /*combining operators with invoke and exec portions doesn't work yet. @@ -354,16 +178,18 @@ void ED_operatortypes_mesh(void) ot= WM_operatortype_append_macro("MESH_OT_duplicate_move", "Add Duplicate", OPTYPE_UNDO|OPTYPE_REGISTER); WM_operatortype_macro_define(ot, "MESH_OT_duplicate"); - WM_operatortype_macro_define(ot, "TFM_OT_translate"); + otmacro= WM_operatortype_macro_define(ot, "TFM_OT_translate"); + RNA_enum_set(otmacro->ptr, "proportional", 0); ot= WM_operatortype_append_macro("MESH_OT_rip_move", "Rip", OPTYPE_UNDO|OPTYPE_REGISTER); WM_operatortype_macro_define(ot, "MESH_OT_rip"); - WM_operatortype_macro_define(ot, "TFM_OT_translate"); + otmacro= WM_operatortype_macro_define(ot, "TFM_OT_translate"); + RNA_enum_set(otmacro->ptr, "proportional", 0); /*ot= WM_operatortype_append_macro("MESH_OT_extrude_move", "Extrude", OPTYPE_UNDO|OPTYPE_REGISTER); WM_operatortype_macro_define(ot, "MESH_OT_extrude"); - otm = WM_operatortype_macro_define(ot, "TFM_OT_translate"); - + otmacro= WM_operatortype_macro_define(ot, "TFM_OT_translate"); + RNA_enum_set(otmacro->ptr, "proportional", 0); RNA_enum_set(otm->ptr, "proportional", 0); RNA_boolean_set(otm->ptr, "mirror", 0); @@ -373,12 +199,15 @@ void ED_operatortypes_mesh(void) } /* note mesh keymap also for other space? */ -void ED_keymap_mesh(wmWindowManager *wm) +void ED_keymap_mesh(wmKeyConfig *keyconf) { - ListBase *keymap= WM_keymap_listbase(wm, "EditMesh", 0, 0); - wmKeymapItem *kmi; + wmKeyMap *keymap; + wmKeyMapItem *kmi; + + keymap= WM_keymap_find(keyconf, "EditMesh", 0, 0); + keymap->poll= ED_operator_editmesh; - WM_keymap_add_item(keymap, "MESH_OT_loopcut", ACTIONMOUSE, KM_PRESS, KM_CTRL, RKEY); + WM_keymap_add_item(keymap, "MESH_OT_loopcut", RKEY, KM_PRESS, KM_CTRL, 0); /* selecting */ /* standard mouse selection goes via space_view3d */ @@ -463,26 +292,40 @@ void ED_keymap_mesh(wmWindowManager *wm) /* add/remove */ WM_keymap_add_item(keymap, "MESH_OT_edge_face_add", FKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "MESH_OT_skin", FKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); /* python */ WM_keymap_add_item(keymap, "MESH_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0); - WM_keymap_add_item(keymap, "OBJECT_OT_mesh_add", AKEY, KM_PRESS, KM_SHIFT, 0); - WM_keymap_add_item(keymap, "MESH_OT_separate", PKEY, KM_PRESS, KM_SHIFT, 0); + + kmi= WM_keymap_add_item(keymap, "WM_OT_call_menu", AKEY, KM_PRESS, KM_SHIFT, 0); + RNA_string_set(kmi->ptr, "name", "INFO_MT_mesh_add"); + + WM_keymap_add_item(keymap, "MESH_OT_separate", PKEY, KM_PRESS, 0, 0); /* use KM_RELEASE because same key is used for tweaks */ WM_keymap_add_item(keymap, "MESH_OT_dupli_extrude_cursor", LEFTMOUSE, KM_RELEASE, KM_CTRL, 0); WM_keymap_add_item(keymap, "MESH_OT_delete", XKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "MESH_OT_delete", DELKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "MESH_OT_fgon_make", FKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "MESH_OT_fgon_clear", FKEY, KM_PRESS, KM_SHIFT|KM_ALT, 0); - WM_keymap_add_item(keymap, "MESH_OT_knife_cut", LEFTMOUSE, KM_PRESS, KM_CTRL, XKEY); + WM_keymap_add_item(keymap, "MESH_OT_knife_cut", LEFTMOUSE, KM_PRESS, 0, KKEY); /* menus */ - WM_keymap_add_item(keymap, "MESH_OT_vertex_specials", VKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "MESH_OT_edge_specials", EKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "MESH_OT_face_specials", FKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "MESH_OT_specials", WKEY, KM_PRESS, 0, 0); + kmi= WM_keymap_add_item(keymap, "WM_OT_call_menu", WKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "name", "VIEW3D_MT_edit_mesh_specials"); + + kmi= WM_keymap_add_item(keymap, "WM_OT_call_menu", FKEY, KM_PRESS, KM_CTRL, 0); + RNA_string_set(kmi->ptr, "name", "VIEW3D_MT_edit_mesh_faces"); + kmi= WM_keymap_add_item(keymap, "WM_OT_call_menu", EKEY, KM_PRESS, KM_CTRL, 0); + RNA_string_set(kmi->ptr, "name", "VIEW3D_MT_edit_mesh_edges"); + + kmi= WM_keymap_add_item(keymap, "WM_OT_call_menu", VKEY, KM_PRESS, KM_CTRL, 0); + RNA_string_set(kmi->ptr, "name", "VIEW3D_MT_edit_mesh_vertices"); + /* UV's */ WM_keymap_add_item(keymap, "UV_OT_mapping_menu", UKEY, KM_PRESS, 0, 0); + + ED_object_generic_keymap(keyconf, keymap, TRUE); } diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 4e356479f9e..629e7bacc20 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -588,7 +588,7 @@ int join_mesh_exec(bContext *C, wmOperator *op) DAG_scene_sort(scene); // removed objects, need to rebuild dag before editmode call ED_object_enter_editmode(C, EM_WAITCURSOR); - ED_object_exit_editmode(C, EM_FREEDATA|EM_WAITCURSOR); + ED_object_exit_editmode(C, EM_FREEDATA|EM_WAITCURSOR|EM_DO_UNDO); WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, scene); @@ -687,7 +687,7 @@ void sort_faces(Scene *scene, View3D *v3d) if (event == 1) Mat4MulMat4(mat, OBACT->obmat, rv3d->viewmat); /* apply the view matrix to the object matrix */ else if (event == 2) { /* sort from cursor */ - if( v3d && v3d->localview ) { + if( v3d && v3d->localvd ) { VECCOPY(cur, v3d->cursor); } else { VECCOPY(cur, scene->cursor); |