diff options
Diffstat (limited to 'source/blender/editors/mesh/editmesh_tools.c')
-rw-r--r-- | source/blender/editors/mesh/editmesh_tools.c | 262 |
1 files changed, 218 insertions, 44 deletions
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 35fc5c1e3bc..5d6d9e314f2 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -37,8 +37,6 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise #include <math.h> #include <float.h> -#include "MEM_guardedalloc.h" - #include "BLO_sys_types.h" // for intptr_t support #include "DNA_meshdata_types.h" @@ -47,6 +45,8 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise #include "DNA_scene_types.h" #include "DNA_key_types.h" +#include "MEM_guardedalloc.h" + #include "RNA_define.h" #include "RNA_access.h" @@ -59,19 +59,13 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise #include "BLI_heap.h" #include "BKE_context.h" -#include "BKE_customdata.h" #include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_key.h" -#include "BKE_library.h" #include "BKE_mesh.h" -#include "BKE_object.h" -#include "BKE_utildefines.h" #include "BKE_bmesh.h" #include "BKE_report.h" -#include "BIF_gl.h" -#include "BIF_glutil.h" #include "WM_api.h" #include "WM_types.h" @@ -80,6 +74,7 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise #include "ED_screen.h" #include "ED_transform.h" #include "ED_view3d.h" +#include "ED_object.h" #include "mesh_intern.h" @@ -481,20 +476,19 @@ static int removedoublesflag_exec(bContext *C, wmOperator *op) { Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data)); - /*char msg[100];*/ - /*int cnt =*/ removedoublesflag(em,1,0,RNA_float_get(op->ptr, "limit")); - /*XXX this messes up last operator panel - if(cnt) - { - sprintf(msg, "Removed %d vertices", cnt); - BKE_report(op->reports, RPT_INFO, msg); - }*/ + int count = removedoublesflag(em,1,0,RNA_float_get(op->ptr, "limit")); + + if(count) { + recalc_editnormals(em); - DAG_id_flush_update(obedit->data, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + } + BKE_reportf(op->reports, RPT_INFO, "Removed %d vertices", count); BKE_mesh_end_editmesh(obedit->data, em); + return OPERATOR_FINISHED; } @@ -648,8 +642,7 @@ void extrude_mesh(Scene *scene, Object *obedit, EditMesh *em, wmOperator *op, sh * This shouldn't be necessary, derived queries should be * automatically building this data if invalid. Or something. */ -// DAG_id_flush_update(obedit->data, OB_RECALC_DATA); - object_handle_update(scene, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); /* individual faces? */ // BIF_TransformSetUndo("Extrude"); @@ -661,7 +654,7 @@ void extrude_mesh(Scene *scene, Object *obedit, EditMesh *em, wmOperator *op, sh // initTransform(TFM_TRANSLATION, CTX_NO_PET|CTX_NO_MIRROR); if(transmode=='n') { mul_m4_v3(obedit->obmat, nor); - sub_v3_v3v3(nor, nor, obedit->obmat[3]); + sub_v3_v3(nor, obedit->obmat[3]); // BIF_setSingleAxisConstraint(nor, "along normal"); } // Transform(); @@ -798,6 +791,7 @@ void MESH_OT_extrude(wmOperatorType *ot) /* properties */ prop= RNA_def_enum(ot->srna, "type", extrude_items, 0, "Type", ""); + RNA_def_property_flag(prop, PROP_HIDDEN); RNA_def_enum_funcs(prop, extrude_itemf); ot->prop= prop; } @@ -1034,11 +1028,11 @@ void MESH_OT_spin(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* props */ - RNA_def_int(ot->srna, "steps", 9, 0, INT_MAX, "Steps", "Steps", 0, INT_MAX); + RNA_def_int(ot->srna, "steps", 9, 0, INT_MAX, "Steps", "Steps", 0, 128); RNA_def_boolean(ot->srna, "dupli", 0, "Dupli", "Make Duplicates"); RNA_def_float(ot->srna, "degrees", 90.0f, -FLT_MAX, FLT_MAX, "Degrees", "Degrees", -360.0f, 360.0f); - RNA_def_float_vector(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX); + RNA_def_float_vector_xyz(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX); RNA_def_float_vector(ot->srna, "axis", 3, NULL, -1.0f, 1.0f, "Axis", "Axis in global view space", -FLT_MAX, FLT_MAX); } @@ -1145,7 +1139,7 @@ void MESH_OT_screw(wmOperatorType *ot) RNA_def_int(ot->srna, "steps", 9, 0, INT_MAX, "Steps", "Steps", 0, 256); RNA_def_int(ot->srna, "turns", 1, 0, INT_MAX, "Turns", "Turns", 0, 256); - RNA_def_float_vector(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX); + RNA_def_float_vector_xyz(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX); RNA_def_float_vector(ot->srna, "axis", 3, NULL, -1.0f, 1.0f, "Axis", "Axis in global view space", -FLT_MAX, FLT_MAX); } @@ -1447,7 +1441,7 @@ static void alter_co(float *co, EditEdge *edge, float smooth, float fractal, int vec1[0]= fac*(float)(0.5-BLI_drand()); vec1[1]= fac*(float)(0.5-BLI_drand()); vec1[2]= fac*(float)(0.5-BLI_drand()); - add_v3_v3v3(co, co, vec1); + add_v3_v3(co, vec1); } } @@ -2729,7 +2723,7 @@ void esubdivideflag(Object *obedit, EditMesh *em, int flag, float smooth, float } } - gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); + gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "subdivideedgenum gh"); // If we are knifing, We only need the selected edges that were cut, so deselect if it was not cut if(beauty & B_KNIFE) { @@ -3094,21 +3088,21 @@ static void givequadverts(EditFace *efa, EditFace *efa1, EditVert **v1, EditVert if VTEST(efa1, 1, efa) { *v3= efa1->v1; - *v4= efa1->v2; + *v4= (efa1->v2 == *v2)? efa1->v3: efa1->v2; vindex[2]= 0; - vindex[3]= 1; + vindex[3]= (efa1->v2 == *v2)? 2: 1; } else if VTEST(efa1, 2, efa) { *v3= efa1->v2; - *v4= efa1->v3; + *v4= (efa1->v3 == *v2)? efa1->v1: efa1->v3; vindex[2]= 1; - vindex[3]= 2; + vindex[3]= (efa1->v3 == *v2)? 0: 2; } else if VTEST(efa1, 3, efa) { *v3= efa1->v3; - *v4= efa1->v1; + *v4= (efa1->v1 == *v2)? efa1->v2: efa1->v1; vindex[2]= 2; - vindex[3]= 0; + vindex[3]= (efa1->v1 == *v2)? 1: 0; } else *v3= *v4= NULL; @@ -3417,7 +3411,7 @@ void join_triangles(EditMesh *em) efaa= (EVPtr *)eed->tmp.p; v1 = v2 = v3 = v4 = NULL; givequadverts(efaa[0], efaa[1], &v1, &v2, &v3, &v4, vindex); - if((v1 && v2 && v3 && v4) && (exist_face(em, v1, v2, v3, v4)==0)){ /*exist_face is very slow! Needs to be adressed.*/ + if((v1 && v2 && v3 && v4) && (exist_face(em, v1, v2, v3, v4)==0)){ /*exist_face is very slow! Needs to be addressed.*/ /*flag for delete*/ eed->f1 |= T2QDELETE; /*create new quad and select*/ @@ -3657,10 +3651,10 @@ static void edge_rotate(EditMesh *em, wmOperator *op, EditEdge *eed, int dir) newFace[1]= EM_face_from_faces(em, face[1], face[0], p[1][1], p[1][2], 4+p[0][1], -1); } else if(fac1 == 4 && fac2 == 3) { - if(dir == DIRECTION_CW) { + if(dir == DIRECTION_CCW) { newFace[0]= EM_face_from_faces(em, face[0], face[1], p[0][1], p[0][2], p[0][3], 4+p[1][1]); newFace[1]= EM_face_from_faces(em, face[1], face[0], p[1][1], p[1][2], 4+p[0][1], -1); - } else if (dir == DIRECTION_CCW) { + } else if (dir == DIRECTION_CW) { newFace[0]= EM_face_from_faces(em, face[0], face[1], p[0][2], 4+p[1][1], p[0][0], p[0][1]); newFace[1]= EM_face_from_faces(em, face[1], face[0], 4+p[0][2], p[1][0], p[1][1], -1); @@ -3669,10 +3663,10 @@ static void edge_rotate(EditMesh *em, wmOperator *op, EditEdge *eed, int dir) } } else if(fac1 == 3 && fac2 == 4) { - if(dir == DIRECTION_CW) { + if(dir == DIRECTION_CCW) { newFace[0]= EM_face_from_faces(em, face[0], face[1], p[0][1], p[0][2], 4+p[1][1], -1); newFace[1]= EM_face_from_faces(em, face[1], face[0], p[1][1], p[1][2], p[1][3], 4+p[0][1]); - } else if (dir == DIRECTION_CCW) { + } else if (dir == DIRECTION_CW) { newFace[0]= EM_face_from_faces(em, face[0], face[1], p[0][0], p[0][1], 4+p[1][2], -1); newFace[1]= EM_face_from_faces(em, face[1], face[0], p[1][1], p[1][2], 4+p[0][1], 4+p[0][2]); @@ -3682,10 +3676,10 @@ static void edge_rotate(EditMesh *em, wmOperator *op, EditEdge *eed, int dir) } else if(fac1 == 4 && fac2 == 4) { - if(dir == DIRECTION_CW) { + if(dir == DIRECTION_CCW) { newFace[0]= EM_face_from_faces(em, face[0], face[1], p[0][1], p[0][2], p[0][3], 4+p[1][1]); newFace[1]= EM_face_from_faces(em, face[1], face[0], p[1][1], p[1][2], p[1][3], 4+p[0][1]); - } else if (dir == DIRECTION_CCW) { + } else if (dir == DIRECTION_CW) { newFace[0]= EM_face_from_faces(em, face[0], face[1], p[0][2], p[0][3], 4+p[1][1], 4+p[1][2]); newFace[1]= EM_face_from_faces(em, face[1], face[0], p[1][2], p[1][3], 4+p[0][1], 4+p[0][2]); @@ -3696,7 +3690,7 @@ static void edge_rotate(EditMesh *em, wmOperator *op, EditEdge *eed, int dir) else return; /* This should never happen */ - if(dir == DIRECTION_CW || (fac1 == 3 && fac2 == 3)) { + if(dir == DIRECTION_CCW || (fac1 == 3 && fac2 == 3)) { verts[0][p[0][1]]->f |= SELECT; verts[1][p[1][1]]->f |= SELECT; } @@ -4091,7 +4085,7 @@ useless: // populate the SlideVerts - vertgh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); + vertgh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "EdgeSlide gh"); look = vertlist; while(look) { i=0; @@ -4259,7 +4253,7 @@ useless: for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) { - uvarray[uvlay_idx] = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); + uvarray[uvlay_idx] = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "EdgeSlideUV gh"); for(ev=em->verts.first;ev;ev=ev->next) { ev->tmp.l = 0; @@ -5162,7 +5156,7 @@ static int blend_from_shape_exec(bContext *C, wmOperator *op) if(add) { mul_v3_fl(co, blend); - add_v3_v3v3(eve->co, eve->co, co); + add_v3_v3(eve->co, co); } else interp_v3_v3v3(eve->co, eve->co, co, blend); @@ -5778,7 +5772,7 @@ static void em_snap_to_center(EditMesh *em) for (eve=em->verts.first; eve; eve=eve->next) { if (eve->f & SELECT) { - add_v3_v3v3(cent, cent, eve->co); + add_v3_v3(cent, eve->co); i++; } } @@ -5863,6 +5857,7 @@ static int merge_exec(bContext *C, wmOperator *op) if(!count) return OPERATOR_CANCELLED; + recalc_editnormals(em); BKE_reportf(op->reports, RPT_INFO, "Removed %d vert%s.", count, (count==1)?"ex":"ices"); @@ -6174,6 +6169,7 @@ static int region_to_loop(bContext *C, wmOperator *op) } em->selectmode = SCE_SELECT_EDGE; + CTX_data_tool_settings(C)->selectmode= em->selectmode; EM_selectmode_set(em); BKE_mesh_end_editmesh(obedit->data, em); @@ -7080,6 +7076,184 @@ void MESH_OT_beautify_fill(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } +/* ********************** SORT FACES ******************* */ + +static void permutate(void *list, int num, int size, int *index) +{ + void *buf; + int len; + int i; + + len = num * size; + + buf = MEM_mallocN(len, "permutate"); + memcpy(buf, list, len); + + for (i = 0; i < num; i++) { + memcpy((char *)list + (i * size), (char *)buf + (index[i] * size), size); + } + MEM_freeN(buf); +} + +/* sort faces on view axis */ +static float *face_sort_floats; +static int float_sort(const void *v1, const void *v2) +{ + float x1, x2; + + x1 = face_sort_floats[((int *) v1)[0]]; + x2 = face_sort_floats[((int *) v2)[0]]; + + if( x1 > x2 ) return 1; + else if( x1 < x2 ) return -1; + return 0; +} + + +static int sort_faces_exec(bContext *C, wmOperator *op) +{ + RegionView3D *rv3d= ED_view3d_context_rv3d(C); + View3D *v3d= CTX_wm_view3d(C); + Object *ob= CTX_data_edit_object(C); + Scene *scene= CTX_data_scene(C); + Mesh *me; + CustomDataLayer *layer; + int i, *index; + int event; + float reverse = 1; + // XXX int ctrl= 0; + + if (!v3d) return OPERATOR_CANCELLED; + + /* This operator work in Object Mode, not in edit mode. + * After talk with Cambell we agree that there is no point to port this to EditMesh right now. + * so for now, we just exit_editmode and enter_editmode at the end of this function. + */ + ED_object_exit_editmode(C, EM_FREEDATA); + + me= ob->data; + if(me->totface==0) { + ED_object_enter_editmode(C, 0); + return OPERATOR_FINISHED; + } + + event= RNA_enum_get(op->ptr, "type"); + + // XXX + //if(ctrl) + // reverse = -1; + + /* create index list */ + index= (int *)MEM_mallocN(sizeof(int) * me->totface, "sort faces"); + for (i = 0; i < me->totface; i++) { + index[i] = i; + } + + face_sort_floats = (float *) MEM_mallocN(sizeof(float) * me->totface, "sort faces float"); + + /* sort index list instead of faces itself + * and apply this permutation to all face layers + */ + if (event == 5) { + /* Random */ + for(i=0; i<me->totface; i++) { + face_sort_floats[i] = BLI_frand(); + } + qsort(index, me->totface, sizeof(int), float_sort); + } else { + MFace *mf; + float vec[3]; + float mat[4][4]; + float cur[3]; + + if (event == 1) + mul_m4_m4m4(mat, OBACT->obmat, rv3d->viewmat); /* apply the view matrix to the object matrix */ + else if (event == 2) { /* sort from cursor */ + if( v3d && v3d->localvd ) { + VECCOPY(cur, v3d->cursor); + } else { + VECCOPY(cur, scene->cursor); + } + invert_m4_m4(mat, OBACT->obmat); + mul_m4_v3(mat, cur); + } + + mf= me->mface; + + for(i=0; i<me->totface; i++, mf++) { + if (event==3) { + face_sort_floats[i] = ((float)mf->mat_nr)*reverse; + } else if (event==4) { + /*selected first*/ + if (mf->flag & ME_FACE_SEL) + face_sort_floats[i] = 0.0; + else + face_sort_floats[i] = reverse; + } else { + /* find the faces center */ + add_v3_v3v3(vec, (me->mvert+mf->v1)->co, (me->mvert+mf->v2)->co); + if (mf->v4) { + add_v3_v3(vec, (me->mvert+mf->v3)->co); + add_v3_v3(vec, (me->mvert+mf->v4)->co); + mul_v3_fl(vec, 0.25f); + } else { + add_v3_v3(vec, (me->mvert+mf->v3)->co); + mul_v3_fl(vec, 1.0f/3.0f); + } /* done */ + + if (event == 1) { /* sort on view axis */ + mul_m4_v3(mat, vec); + face_sort_floats[i] = vec[2] * reverse; + } else if(event == 2) { /* distance from cursor*/ + face_sort_floats[i] = len_v3v3(cur, vec) * reverse; /* back to front */ + } + } + } + qsort(index, me->totface, sizeof(int), float_sort); + } + + MEM_freeN(face_sort_floats); + for(i = 0; i < me->fdata.totlayer; i++) { + layer = &me->fdata.layers[i]; + permutate(layer->data, me->totface, CustomData_sizeof(layer->type), index); + } + + MEM_freeN(index); + DAG_id_flush_update(ob->data, OB_RECALC_DATA); + + /* Return to editmode. */ + ED_object_enter_editmode(C, 0); + + return OPERATOR_FINISHED; +} + +void MESH_OT_sort_faces(wmOperatorType *ot) +{ + static EnumPropertyItem type_items[]= { + { 1, "VIEW_AXIS", 0, "View Axis", "" }, + { 2, "CURSOR_DISTANCE", 0, "Cursor Distance", "" }, + { 3, "MATERIAL", 0, "Material", "" }, + { 4, "SELECTION", 0, "Selection", "" }, + { 5, "RANDOMIZE", 0, "Randomize", "" }, + { 0, NULL, 0, NULL, NULL }}; + + /* identifiers */ + ot->name= "Sort Faces"; // XXX (Ctrl to reverse)%t| + ot->description= "The faces of the active Mesh Object are sorted, based on the current view."; + ot->idname= "MESH_OT_sort_faces"; + + /* api callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= sort_faces_exec; + ot->poll= ED_operator_editmesh; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + ot->prop= RNA_def_enum(ot->srna, "type", type_items, 0, "Type", ""); +} + /********************** Quad/Tri Operators *************************/ static int quads_convert_to_tris_exec(bContext *C, wmOperator *op) |