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:
authorJoseph Eagar <joeedh@gmail.com>2009-10-23 03:22:05 +0400
committerJoseph Eagar <joeedh@gmail.com>2009-10-23 03:22:05 +0400
commit8f788c64db587e74079d812dbcea40c2bd4b91ff (patch)
treec767e8318a9e7aded16be6cab2042f3ea11e7912 /source/blender/editors/mesh
parent36bb566d4e6e06e08d782d610d60d755cbda2396 (diff)
merge with trunk/2.5 at r23876
[[Split portion of a mixed commit.]]
Diffstat (limited to 'source/blender/editors/mesh')
-rw-r--r--source/blender/editors/mesh/SConscript7
-rw-r--r--source/blender/editors/mesh/bmesh_select.c116
-rw-r--r--source/blender/editors/mesh/bmesh_tools.c74
-rw-r--r--source/blender/editors/mesh/editface.c61
-rw-r--r--source/blender/editors/mesh/editmesh.c21
-rw-r--r--source/blender/editors/mesh/editmesh_add.c240
-rw-r--r--source/blender/editors/mesh/editmesh_mods.c27
-rw-r--r--source/blender/editors/mesh/loopcut.c65
-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.h8
-rw-r--r--source/blender/editors/mesh/mesh_ops.c237
-rw-r--r--source/blender/editors/mesh/meshtools.c4
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);