diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 560c5b4aef0..957a97b61fa 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -693,6 +693,7 @@ BMOpDefine def_dupeop = { {BMOP_OPSLOT_MAPPING, "facemap"}, {BMOP_OPSLOT_MAPPING, "boundarymap"}, {BMOP_OPSLOT_MAPPING, "isovertmap"}, + {BMOP_OPSLOT_PNT, "dest"}, /*destination bmesh, if NULL will use current one*/ {0} /*null-terminating sentinel*/}, dupeop_exec, 0 @@ -704,6 +705,7 @@ BMOpDefine def_splitop = { {BMOP_OPSLOT_ELEMENT_BUF, "geomout"}, {BMOP_OPSLOT_MAPPING, "boundarymap"}, {BMOP_OPSLOT_MAPPING, "isovertmap"}, + {BMOP_OPSLOT_PNT, "dest"}, /*destination bmesh, if NULL will use current one*/ {0} /*null-terminating sentinel*/}, splitop_exec, 0 diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index 2f298902c3c..14dfac18cba 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -1250,7 +1250,6 @@ int BMO_VInitOpf(BMesh *bm, BMOperator *op, char *fmt, va_list vlist) return 1; error: BMO_Finish_Op(bm, op); - free(fmt); return 0; } diff --git a/source/blender/bmesh/operators/bmesh_dupeops.c b/source/blender/bmesh/operators/bmesh_dupeops.c index b67ff66097d..86ab8ed7cf4 100644 --- a/source/blender/bmesh/operators/bmesh_dupeops.c +++ b/source/blender/bmesh/operators/bmesh_dupeops.c @@ -156,7 +156,6 @@ static void copy_mesh(BMOperator *op, BMesh *source, BMesh *target) BMVert *v = NULL, *v2; BMEdge *e = NULL, **edar = NULL; - BMLoop *l = NULL; BMFace *f = NULL; BMIter verts; @@ -314,12 +313,16 @@ BMesh *bmesh_make_mesh_from_mesh(BMesh *bm, int allocsize[4]) void dupeop_exec(BMesh *bm, BMOperator *op) { BMOperator *dupeop = op; + BMesh *bm2 = BMO_Get_Pnt(op, "dest"); + if (!bm2) + bm2 = bm; + /*flag input*/ BMO_Flag_Buffer(bm, dupeop, "geom", DUPE_INPUT, BM_ALL); /*use the internal copy function*/ - copy_mesh(dupeop, bm, bm); + copy_mesh(dupeop, bm, bm2); /*Output*/ /*First copy the input buffers to output buffers - original data*/ diff --git a/source/blender/editors/mesh/bmesh_tools.c b/source/blender/editors/mesh/bmesh_tools.c index ae37c6f9337..d1febba944d 100644 --- a/source/blender/editors/mesh/bmesh_tools.c +++ b/source/blender/editors/mesh/bmesh_tools.c @@ -60,6 +60,7 @@ #include "BLI_heap.h" #include "BLI_array.h" +#include "BKE_material.h" #include "BKE_context.h" #include "BKE_customdata.h" #include "BKE_depsgraph.h" @@ -71,6 +72,7 @@ #include "BKE_bmesh.h" #include "BKE_report.h" #include "BKE_tessmesh.h" +#include "BKE_main.h" #include "BIF_gl.h" #include "BIF_glutil.h" @@ -83,6 +85,7 @@ #include "ED_util.h" #include "ED_screen.h" #include "ED_transform.h" +#include "ED_object.h" #include "UI_interface.h" @@ -1653,7 +1656,7 @@ void EDBM_reveal_mesh(BMEditMesh *em) BMIter iter; BMHeader *ele; int i, types[3] = {BM_VERTS_OF_MESH, BM_EDGES_OF_MESH, BM_FACES_OF_MESH}; - int sels[3] = {1, !(em->selectmode & SCE_SELECT_VERTEX), !(em->selectmode & SCE_SELECT_VERTEX | SCE_SELECT_EDGE)}; + int sels[3] = {1, !(em->selectmode & SCE_SELECT_VERTEX), !(em->selectmode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE))}; for (i=0; i<3; i++) { BM_ITER(ele, &iter, em->bm, types[i], NULL) { @@ -2347,8 +2350,6 @@ static EnumPropertyItem *merge_type_itemf(bContext *C, PointerRNA *ptr, int *fre void MESH_OT_merge(wmOperatorType *ot) { - PropertyRNA *prop; - /* identifiers */ ot->name= "Merge"; ot->idname= "MESH_OT_merge"; @@ -3720,26 +3721,98 @@ void MESH_OT_knife_cut(wmOperatorType *ot) RNA_def_int(ot->srna, "cursor", BC_KNIFECURSOR, 0, INT_MAX, "Cursor", "", 0, INT_MAX); } +static int mesh_separate_selected(Main *bmain, Scene *scene, Base *editbase, wmOperator *wmop) +{ + Base *basenew; + BMIter iter; + BMVert *v; + BMEdge *e; + Object *obedit = editbase->object; + Mesh *me = obedit->data; + BMEditMesh *em = me->edit_btmesh; + BMesh *bmnew; + int allocsize[] = {512, 512, 2048, 512}; + + if (!em) + return OPERATOR_CANCELLED; + + bmnew = BM_Make_Mesh(allocsize); + CustomData_copy(&bmnew->vdata, &em->bm->vdata, CD_MASK_BMESH, CD_CALLOC, 0); + CustomData_copy(&bmnew->edata, &em->bm->edata, CD_MASK_BMESH, CD_CALLOC, 0); + CustomData_copy(&bmnew->ldata, &em->bm->ldata, CD_MASK_BMESH, CD_CALLOC, 0); + CustomData_copy(&bmnew->pdata, &em->bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0); + + CustomData_bmesh_init_pool(&bmnew->vdata, allocsize[0]); + CustomData_bmesh_init_pool(&bmnew->edata, allocsize[1]); + CustomData_bmesh_init_pool(&bmnew->ldata, allocsize[2]); + CustomData_bmesh_init_pool(&bmnew->pdata, allocsize[3]); + + basenew= ED_object_add_duplicate(bmain, scene, editbase, USER_DUP_MESH); /* 0 = fully linked */ + assign_matarar(basenew->object, give_matarar(obedit), *give_totcolp(obedit)); /* new in 2.5 */ + + ED_base_object_select(basenew, BA_DESELECT); + + EDBM_CallOpf(em, wmop, "dupe geom=%hvef dest=%p", BM_SELECT, bmnew); + EDBM_CallOpf(em, wmop, "del geom=%hvef context=%i", BM_SELECT, DEL_FACES); + + /*clean up any loose edges*/ + BM_ITER(e, &iter, em->bm, BM_EDGES_OF_MESH, NULL) { + if (BM_TestHFlag(e, BM_HIDDEN)) + continue; + + if (BM_Edge_FaceCount(e) != 0) + BM_Select(em->bm, e, 0); /*deselect*/ + } + EDBM_CallOpf(em, wmop, "del geom=%hvef context=%i", BM_SELECT, DEL_EDGES); + + /*clean up any loose verts*/ + BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { + if (BM_TestHFlag(v, BM_HIDDEN)) + continue; + + if (BM_Vert_EdgeCount(v) != 0) + BM_Select(em->bm, v, 0); /*deselect*/ + } + + EDBM_CallOpf(em, wmop, "del geom=%hvef context=%i", BM_SELECT, DEL_VERTS); + + BM_Compute_Normals(bmnew); + BMO_CallOpf(bmnew, "bmesh_to_mesh mesh=%p object=%p", basenew->object->data, basenew->object); + + BM_Free_Mesh(bmnew); + + return 1; +} + +static int mesh_separate_material(Main *bmain, Scene *scene, Base *editbase, wmOperator *wmop) +{ + return 0; +} + +static int mesh_separate_loose(Main *bmain, Scene *scene, Base *editbase, wmOperator *wmop) +{ + return 0; +} + static int mesh_separate_exec(bContext *C, wmOperator *op) { -#if 0 + Main *bmain = CTX_data_main(C); Scene *scene= CTX_data_scene(C); Base *base= CTX_data_active_base(C); int retval= 0, type= RNA_enum_get(op->ptr, "type"); if(type == 0) - retval= mesh_separate_selected(scene, base); + retval= mesh_separate_selected(bmain, scene, base, op); else if(type == 1) - retval= mesh_separate_material (scene, base); + retval= mesh_separate_material (bmain, scene, base, op); else if(type == 2) - retval= mesh_separate_loose(scene, base); + retval= mesh_separate_loose(bmain, scene, base, op); if(retval) { WM_event_add_notifier(C, NC_GEOM|ND_DATA, base->object->data); return OPERATOR_FINISHED; } -#endif return OPERATOR_CANCELLED; } @@ -3767,7 +3840,7 @@ void MESH_OT_separate(wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - RNA_def_enum(ot->srna, "type", prop_separate_types, 0, "Type", ""); + ot->prop = RNA_def_enum(ot->srna, "type", prop_separate_types, 0, "Type", ""); } diff --git a/source/blender/editors/mesh/knifetool.c b/source/blender/editors/mesh/knifetool.c index bbe0adc9d27..89b63183c31 100755 --- a/source/blender/editors/mesh/knifetool.c +++ b/source/blender/editors/mesh/knifetool.c @@ -115,11 +115,12 @@ typedef struct KnifeEdge { #define DEL 8 typedef struct BMEdgeHit { - BMEdge *e; + KnifeEdge *kfe; float hit[3]; float shit[3]; float l; /*lambda along line*/ BMVert *v; //set if snapped to a vert + BMFace *f; } BMEdgeHit; /* struct for properties used while drawing */ @@ -495,18 +496,20 @@ static void knife_add_cut(knifetool_opdata *kcd) lh = kcd->linehits; lastlh = firstlh = NULL; for (i=0; itotlinehit; i++, (lastlh=lh), lh++) { + BMFace *f = lastlh ? lastlh->f : lh->f; + if (lastlh && len_v3v3(lastlh->hit, lh->hit) == 0.0f) { if (!firstlh) firstlh = lastlh; continue; } else if (lastlh && firstlh) { if (firstlh->v || lastlh->v) { - BMVert *bmv = firstlh->v ? firstlh->v : lastlh->v; + KnifeVert *kfv = firstlh->v ? firstlh->v : lastlh->v; - kcd->prevvert = get_bm_knife_vert(kcd, bmv); + kcd->prevvert = kfv; copy_v3_v3(kcd->prevco, firstlh->hit); kcd->prevedge = NULL; - kcd->prevbmface = firstlh->e->l ? firstlh->e->l->f : NULL; + kcd->prevbmface = f; } lastlh = firstlh = NULL; } @@ -514,9 +517,9 @@ static void knife_add_cut(knifetool_opdata *kcd) if (!lastlh && len_v3v3(kcd->prevco, lh->hit) < FLT_EPSILON*10) continue; - kcd->curedge = get_bm_knife_edge(kcd, lh->e); - kcd->curbmface = kcd->curedge->e->l ? kcd->curedge->e->l->f : NULL; - kcd->curvert = lh->v ? get_bm_knife_vert(kcd, lh->v) : NULL; + kcd->curedge = lh->kfe; + kcd->curbmface = lh->f; + kcd->curvert = lh->v; copy_v3_v3(kcd->vertco, lh->hit); knife_add_single_cut(kcd); @@ -607,17 +610,17 @@ static void knifetool_draw(const bContext *C, ARegion *ar, void *arg) for (i=0; itotlinehit; i++, lh++) { float sv1[3], sv2[3]; - view3d_project_float_v3(kcd->ar, lh->e->v1->co, sv1, kcd->projmat); - view3d_project_float_v3(kcd->ar, lh->e->v2->co, sv2, kcd->projmat); + view3d_project_float_v3(kcd->ar, lh->kfe->v1->co, sv1, kcd->projmat); + view3d_project_float_v3(kcd->ar, lh->kfe->v2->co, sv2, kcd->projmat); if (len_v2v2(lh->shit, sv1) < kcd->vthresh/4) { - copy_v3_v3(lh->hit, lh->e->v1->co); + copy_v3_v3(lh->hit, lh->kfe->v1->co); glVertex3fv(lh->hit); - lh->v = lh->e->v1; + lh->v = lh->kfe->v1; } else if (len_v2v2(lh->shit, sv2) < kcd->vthresh/4) { - copy_v3_v3(lh->hit, lh->e->v2->co); + copy_v3_v3(lh->hit, lh->kfe->v2->co); glVertex3fv(lh->hit); - lh->v = lh->e->v2; + lh->v = lh->kfe->v2; } } glEnd(); @@ -709,34 +712,45 @@ BMEdgeHit *knife_edge_tri_isect(knifetool_opdata *kcd, BMBVHTree *bmtree, float ls = (BMLoop**)kcd->em->looptris[result->indexA]; for (j=0; j<3; j++) { - if (isect_line_tri_v3(ls[j]->e->v1->co, ls[j]->e->v2->co, v1, v2, v3, &lambda, uv)) { - float no[3], view[3], sp[3]; + ListBase *lst = knife_get_face_kedges(kcd, ls[j]->f); + Ref *ref; - sub_v3_v3v3(p, ls[j]->e->v2->co, ls[j]->e->v1->co); - mul_v3_fl(p, lambda); - add_v3_v3(p, ls[j]->e->v1->co); + for (ref=lst->first; ref; ref=ref->next) { + KnifeEdge *kfe = ref->ref; - view3d_project_float_v3(kcd->ar, p, sp, kcd->projmat); - view3d_unproject(mats, view, sp[0], sp[1], 0.0f); - sub_v3_v3v3(view, p, view); - normalize_v3(view); - - copy_v3_v3(no, view); - mul_v3_fl(no, -0.00001); - - /*go backwards toward view a bit*/ - add_v3_v3(p, no); - - if (!BMBVH_RayCast(bmtree, p, no, NULL) && !BLI_smallhash_haskey(ehash, (intptr_t)ls[j]->e)) { - BMEdgeHit hit; + if (isect_line_tri_v3(kfe->v1->co, kfe->v2->co, v1, v2, v3, &lambda, uv)) { + float no[3], view[3], sp[3]; - hit.e = ls[j]->e; - hit.v = NULL; - copy_v3_v3(hit.hit, p); - view3d_project_float_v3(kcd->ar, hit.hit, hit.shit, kcd->projmat); + sub_v3_v3v3(p, kfe->v2->co, kfe->v1->co); + mul_v3_fl(p, lambda); + add_v3_v3(p, kfe->v1->co); - BLI_array_append(edges, hit); - BLI_smallhash_insert(ehash, (intptr_t)ls[j]->e, NULL); + view3d_project_float_v3(kcd->ar, p, sp, kcd->projmat); + view3d_unproject(mats, view, sp[0], sp[1], 0.0f); + sub_v3_v3v3(view, p, view); + normalize_v3(view); + + copy_v3_v3(no, view); + mul_v3_fl(no, -0.00001); + + /*go backwards toward view a bit*/ + add_v3_v3(p, no); + + if (!BMBVH_RayCast(bmtree, p, no, NULL) && !BLI_smallhash_haskey(ehash, (intptr_t)kfe)) { + BMEdgeHit hit; + + hit.kfe = kfe; + hit.v = NULL; + + knife_find_basef(kcd, kfe); + hit.f = kfe->basef; + + copy_v3_v3(hit.hit, p); + view3d_project_float_v3(kcd->ar, hit.hit, hit.shit, kcd->projmat); + + BLI_array_append(edges, hit); + BLI_smallhash_insert(ehash, (intptr_t)kfe, NULL); + } } } } @@ -1484,13 +1498,18 @@ static int knifetool_modal (bContext *C, wmOperator *op, wmEvent *event) case ESCKEY: case RETKEY: /* confirm */ // XXX hardcoded if (event->val == KM_RELEASE) { - /* finish */ - ED_region_tag_redraw(kcd->ar); - - knifetool_finish(C, op); - knifetool_exit(C, op); - - return OPERATOR_FINISHED; + if (kcd->mode == MODE_DRAGGING && event->type == ESCKEY) { + kcd->mode = MODE_IDLE; + ED_region_tag_redraw(kcd->ar); + } else { + /* finish */ + ED_region_tag_redraw(kcd->ar); + + knifetool_finish(C, op); + knifetool_exit(C, op); + + return OPERATOR_FINISHED; + } } ED_region_tag_redraw(kcd->ar); diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 6d8ae1bb6d3..92de95252c3 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -1024,7 +1024,6 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) } } - /* setting PET flag only if property exist in operator. Otherwise, assume it's not supported */ if (op && RNA_struct_find_property(op->ptr, "proportional")) { if (RNA_property_is_set(op->ptr, "proportional")) @@ -1038,9 +1037,8 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) break; } } - } - else - { + else + { /* use settings from scene only if modal */ if (t->flag & T_MODAL) { @@ -1058,7 +1056,37 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) t->flag |= T_PROP_EDIT; } } + } } + + if (op && RNA_struct_find_property(op->ptr, "proportional_size") && RNA_property_is_set(op->ptr, "proportional_size")) + { + t->prop_size = RNA_float_get(op->ptr, "proportional_size"); + } + else + { + t->prop_size = ts->proportional_size; + } + + + /* TRANSFORM_FIX_ME rna restrictions */ + if (t->prop_size <= 0) + { + t->prop_size = 1.0f; + } + + if (op && RNA_struct_find_property(op->ptr, "proportional_edit_falloff") && RNA_property_is_set(op->ptr, "proportional_edit_falloff")) + { + t->prop_mode = RNA_enum_get(op->ptr, "proportional_edit_falloff"); + } + else + { + t->prop_mode = ts->prop_mode; + } + } + else /* add not pet option to context when not available */ + { + t->options |= CTX_NO_PET; } setTransformViewMatrices(t);